vframe.hpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.45 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 
00025 // vframes are virtual stack frames representing source level activations.
00026 // A deltaVFrame represents an activation of a Delta level method. A single
00027 // frame may hold several source level activations in the case of 
00028 // optimized code. The debugging stored with the optimized code enables
00029 // us to unfold a frame as a stack of vframes.
00030 // A cVFrame represents an activation of a non-Delta method.
00031 
00032 // The vframe inheritance hierarchy:
00033 // - vframe
00034 //   - deltaVFrame
00035 //     - interpretedVFrame
00036 //     - compiledVFrame
00037 //     - deoptimizedVFrame  ; special deltaVFrame for deoptimized off stack VFrames
00038 //   - cVFrame
00039 //     - cChunk             ; special frame created when entering Delta from C
00040 
00041 class vframe: public PrintableResourceObj {
00042  private:
00043   // Interface for the accessing the callees argument.
00044   // Must be provided for all vframes calling deltaVFrames.
00045   virtual oop callee_argument_at(int index) const;
00046 
00047  protected:
00048   frame _fr;
00049 
00050   vframe(const frame* fr) { _fr = *fr; }        // for subclass use only
00051 
00052  public:
00053   // constructor: creates bottom (most recent) vframe from a frame
00054   static vframe* new_vframe(frame* f);
00055 
00056   // returns the frame
00057   frame fr() const { return _fr; }
00058 
00059   // returns the sender vframe
00060   virtual vframe* sender() const;
00061 
00062   // answers if the receiver is the top vframe in the frame, i.e., if the sender vframe 
00063   // is in the caller frame
00064   virtual bool is_top() const { return true; }
00065 
00066   // returns top vframe within same frame (see is_top())        
00067   virtual vframe* top() const;          
00068 
00069   // comparison operation
00070   virtual bool equal(const vframe* f) const;
00071 
00072   // type testing operations
00073   virtual bool is_c_frame()           const { return false; }
00074   virtual bool is_c_chunk()           const { return false; }
00075   virtual bool is_delta_frame()       const { return false; }
00076   virtual bool is_interpreted_frame() const { return false; }
00077   virtual bool is_compiled_frame()    const { return false; }
00078   virtual bool is_deoptimized_frame() const { return false; }
00079 
00080   // printing operations
00081   virtual void print_value() const;
00082   virtual void print();
00083 
00084   // verify operations
00085   virtual void verify() const {};
00086 
00087   // friends
00088   friend class interpretedVFrame;
00089   friend class compiledVFrame;
00090   friend class cVFrame;
00091   friend class deltaVFrame;
00092   friend class deoptimizedVFrame;
00093 };
00094 
00095 class deltaVFrame: public vframe {
00096  private:
00097    oop callee_argument_at(int index) const; // see vframe
00098 
00099  public:
00100   // constructor
00101   deltaVFrame(const frame* fr) : vframe(fr) {}
00102 
00103   bool is_delta_frame() const   { return true; }
00104 
00105   // returns the receiver (block for block invoc.)
00106   virtual oop receiver() const                  = 0;
00107 
00108   // returns the active method
00109   virtual methodOop method() const              = 0;
00110 
00111   // returns the current byte code index
00112   virtual int bci() const                       = 0;
00113 
00114   virtual oop temp_at(int offset) const         = 0;
00115   virtual oop expression_at(int index) const    = 0;
00116   virtual oop context_temp_at(int offset) const = 0;
00117 
00118   // Returns the interpreter contextOop for this vframe.
00119   // If the frame is optimized a converted context will be returned.
00120   // Returns NULL is canonical form has no context.
00121   // (Only used during deoptimization)
00122   virtual contextOop canonical_context() const = 0;
00123 
00124   // returns the expression stack
00125   virtual GrowableArray<oop>* expression_stack() const = 0;
00126 
00127   // returns the lexical scope of an activation
00128   // - method activations yield NULL.
00129   // - pure block activations yield NULL.
00130   // - non lifo block activations yield NULL.
00131   // - other block activations yield the parent activation
00132   //   if the parent frame resides on the same stack, NULL otherwise!
00133   virtual deltaVFrame* parent() const           = 0;
00134   
00135   // returns the nearest delta vframe in the sender chain
00136   deltaVFrame* sender_delta_frame() const; 
00137 
00138   // returns the arguments
00139   GrowableArray<oop>* arguments() const;
00140 
00141   // arguments are numbered from 1 to n
00142   oop argument_at(int index) const;
00143 
00144   // printing operations
00145   void print();
00146   void print_activation(int index) const;
00147 
00148   // verify operations
00149   void verify() const;
00150   virtual void verify_debug_info() const {};
00151 };
00152 
00153 // Layout of an interpreter frame:
00154 // sp-> [expressions ] *   ^
00155 //      [temps       ] *   |
00156 //      [hp          ]    -2
00157 //      [receiver    ]    -1
00158 // fp-> [link        ]     0
00159 //      [return pc   ]    +1
00160 //      [arguments   ]    +2
00161 
00162 class interpretedVFrame: public deltaVFrame {
00163  public: 
00164   // Constructor
00165   interpretedVFrame(frame* fr) : deltaVFrame(fr) {};
00166 
00167   // Sets the receiver object
00168   void set_receiver(oop obj);
00169 
00170   // Accessors for HP
00171   u_char* hp() const;
00172   void  set_hp(u_char* p);
00173 
00174   // Sets temporaries
00175   void temp_at_put(int offset, oop obj);
00176 
00177   // Sets element on expression stack
00178   void expression_at_put(int index, oop obj);
00179 
00180   // Returns the contextOop for this interpreter frame
00181   // NULL is returned is no context exists.
00182   contextOop interpreter_context() const;
00183 
00184  private:
00185   static const int temp_offset;
00186   static const int hp_offset;
00187   static const int receiver_offset;
00188   static const int argument_offset;
00189   oop* expression_addr(int offset) const;
00190   bool has_interpreter_context() const;
00191 
00192  public:
00193   // Virtuals from vframe
00194   bool is_interpreted_frame() const     { return true; }
00195   bool equal(const vframe* f) const;
00196 
00197  public:
00198   // Virtuals from deltaVFrame
00199   oop receiver() const;
00200   methodOop method() const;
00201   int bci() const;
00202   oop temp_at(int offset) const;
00203   oop expression_at(int index) const;
00204   oop context_temp_at(int offset) const;
00205   contextOop canonical_context() const;
00206   GrowableArray<oop>* expression_stack() const;
00207   deltaVFrame* parent() const;
00208   void verify() const;
00209 };
00210 
00211 #ifdef DELTA_COMPILER
00212 
00213 class compiledVFrame: public deltaVFrame {
00214  public:
00215   // Constructors
00216   static compiledVFrame* new_vframe(const frame* fr, ScopeDesc* sd, int bci);
00217   compiledVFrame(const frame* fr, ScopeDesc* sd, int bci);
00218 
00219   // Returns the active nmethod
00220   nmethod*  code() const;
00221 
00222   // Returns the scopeDesc
00223   ScopeDesc* scope() const { return sd; }
00224 
00225   // Returns the contextOop for this interpreter frame
00226   // NULL is returned is no context exists.
00227   contextOop compiledVFrame::compiled_context() const;
00228 
00229   // Rewind the bci one step
00230   void rewind_bci(); 
00231 
00232   // Returns the scope for the parent.
00233   virtual ScopeDesc* parent_scope() const = 0;
00234 
00235  protected:
00236   ScopeDesc* sd;
00237   int        _bci;
00238 
00239   static contextOop compute_canonical_context(ScopeDesc* sd, const compiledVFrame* vf, contextOop con = NULL);
00240   static oop        resolve_name             (NameDesc* nd,  const compiledVFrame* vf, contextOop con = NULL);
00241   static oop        resolve_location         (Location loc,  const compiledVFrame* vf, contextOop con = NULL);
00242 
00243   // The filler_obj is used during deoptimization for values that couldn't be retrieved.
00244   // - stack temps if the frame is absent
00245   // - context variables if the frame or optimized context is absent.
00246   // In the ideal situation this should never be used but is works great as a defensive mechanism.
00247   static oop filler_oop();
00248 
00249   // Returns the bci for a scope desc. 
00250   // d must belong to the same nmethod and be in the sender chain.
00251   int  bci_for(ScopeDesc* d) const;
00252 
00253   friend struct MemoizedBlockNameDesc;
00254   friend class  blockClosureOopDesc;
00255  public:
00256   // Virtuals defined in vframe
00257   bool is_compiled_frame() const { return true; }
00258   vframe* sender() const;
00259   bool equal(const vframe* f) const;
00260 
00261  public:
00262   // Virtuals defined in deltaVFrame
00263   methodOop method() const;
00264   int  bci() const;
00265   oop temp_at(int offset) const;
00266   oop expression_at(int index) const;
00267   oop context_temp_at(int offset) const;
00268   GrowableArray<oop>* expression_stack() const;
00269   void verify() const;
00270   void verify_debug_info() const;
00271 };
00272 
00273 class compiledMethodVFrame : public compiledVFrame {
00274  public:
00275   // Constructor
00276   compiledMethodVFrame(const frame* fr, ScopeDesc* sd, int bci);
00277 
00278  public:
00279   // Virtuals defined in vframe
00280   bool is_top() const;
00281 
00282  public:
00283   // Virtuals defined in deltaVFrame
00284   deltaVFrame* parent() const { return NULL; }
00285   contextOop canonical_context() const;
00286   oop  receiver() const;
00287   // Virtuals defined in compiledVFrame
00288   ScopeDesc* parent_scope() const { return NULL; }
00289 };
00290 
00291 class compiledBlockVFrame : public compiledVFrame {
00292  public:
00293   // Constructor
00294   compiledBlockVFrame(const frame* fr, ScopeDesc* sd, int bci);
00295 
00296  public:
00297   // Virtuals defined in vframe
00298   bool is_top() const;
00299 
00300  public:
00301   // Virtuals defined in deltaVFrame
00302   deltaVFrame* parent() const;
00303   contextOop canonical_context() const;
00304   oop  receiver() const;
00305   // Virtuals defined in compiledVFrame
00306   ScopeDesc* parent_scope() const;
00307 };
00308 
00309 class compiledTopLevelBlockVFrame : public compiledVFrame {
00310  public:
00311   // Constructor
00312   compiledTopLevelBlockVFrame(const frame* fr, ScopeDesc* sd, int bci);
00313 
00314  public:
00315   // Virtuals defined in vframe
00316   bool is_top() const { return true; }
00317 
00318  public:
00319   // Virtuals defined in deltaVFrame
00320   oop  receiver() const;
00321   contextOop canonical_context() const;
00322   deltaVFrame* parent() const;
00323   // Virtuals defined in compiledVFrame
00324   ScopeDesc* parent_scope() const;
00325 };
00326 
00327 // A deoptimizedVFrame is represented by a frame and an offset
00328 // into the packed array of frames.
00329 
00330 class deoptimizedVFrame: public deltaVFrame {
00331  public:
00332   // Constructor
00333   deoptimizedVFrame(const frame* fr);
00334   deoptimizedVFrame(const frame* fr, int offset);
00335 
00336   // Returns the contextOop for this unoptimized frame
00337   // NULL is returned is no context exists.
00338   contextOop deoptimized_context() const;
00339 
00340  private:
00341   int offset;
00342   objArrayOop frame_array;
00343 
00344   // Reitrieves the frame array from the frame
00345   objArrayOop retrieve_frame_array() const;
00346 
00347   // Returns the oop at offset+index
00348   oop  obj_at(int index) const;
00349   int  end_of_expressions() const;
00350 
00351   enum {
00352     receiver_offset     = 0,
00353     method_offset       = 1,
00354     bci_offset          = 2,
00355     locals_size_offset  = 3,
00356     first_temp_offset   = 4,
00357   };
00358 
00359   friend class StackChunkBuilder;
00360 
00361  public:
00362   // Virtuals defined in vframe
00363   bool equal(const vframe* f) const;
00364   bool is_deoptimized_frame() const { return true; }
00365   vframe* sender() const;
00366   bool is_top() const;
00367 
00368  public:
00369   // Virtuals defined in deltaVFrame
00370   oop receiver() const;
00371   methodOop method() const;
00372   int bci() const;
00373   deltaVFrame* parent() const { return NULL; }
00374   oop temp_at(int offset) const;
00375   oop expression_at(int index) const;
00376   oop context_temp_at(int offset) const;
00377   GrowableArray<oop>* expression_stack() const;
00378   contextOop canonical_context() const;
00379 };
00380 
00381 #endif
00382 
00383 class cVFrame: public vframe {
00384  public:
00385   // Constructor
00386   cVFrame(const frame* fr) : vframe(fr) {}
00387 
00388  public:
00389   // Virtuals defined in vframe
00390   bool is_c_frame() const { return true; }
00391   void print_value() const;
00392   void print();
00393 };
00394 
00395 class cChunk: public cVFrame {
00396  public:
00397   // Constructor
00398   cChunk(const frame* fr) : cVFrame(fr) {}
00399 
00400  public:
00401   // Virtuals defined in vframe
00402   bool is_c_chunk() const { return true; }
00403   vframe* sender() const;
00404   void print_value() const;
00405   void print();
00406 
00407  private:
00408   // Virtual defined in vframe
00409   oop callee_argument_at(int index) const;
00410 };

Generated on Mon Oct 9 13:37:30 2006 for Strongtalk VM by  doxygen 1.4.7