scopeDesc.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996, LongView Technologies L.L.C. $Revision: 1.42 $ */
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 #ifdef DELTA_COMPILER
00025 
00026 class NameDescClosure {
00027  public:
00028   virtual void arg          (int no, NameDesc* a, char* pc) {}
00029   virtual void temp         (int no, NameDesc* t, char* pc) {}
00030   virtual void context_temp (int no, NameDesc* c, char* pc) {}
00031   virtual void stack_expr   (int no, NameDesc* e, char* pc) {}
00032 };
00033 
00034 
00035 const int16 IllegalBCI  =    -1;
00036 const int16 PrologueBCI =     0;
00037 const int16 EpilogueBCI = 32766;
00038 
00039 // use the following functions to compare bcis; they handle PrologueBCI et al.
00040 // negative if bci1 is before bci2, 0 if same, positive if after
00041 int compareBCI(int bci1, int bci2);
00042 
00043 inline bool bciLT(int bci1, int bci2) { return compareBCI(bci1, bci2) <  0; }
00044 inline bool bciLE(int bci1, int bci2) { return compareBCI(bci1, bci2) <= 0; }
00045 inline bool bciGT(int bci1, int bci2) { return compareBCI(bci1, bci2) >  0; }
00046 inline bool bciGE(int bci1, int bci2) { return compareBCI(bci1, bci2) >= 0; }
00047 
00048 // Blocks belonging to scopes that aren't described (because they
00049 // can't possibly be visible to the user) get IllegalDescOffset as
00050 // their desc offset
00051 const int IllegalDescOffset = -2;
00052 
00053 
00054 // scopeDescs contain the information that makes source-level debugging of
00055 // nmethods possible; each scopeDesc describes a method activation
00056 // Class Hierarchy:
00057 //  - ScopeDesc          (abstract)
00058 //    - MethodScopeDesc
00059 //    - BlockScopeDesc
00060 //    - TopLevelScopeDesc
00061 //  - NonInlinedBlockScopeDesc
00062 
00063 class ScopeDesc : public PrintableResourceObj {         // abstract
00064  protected:
00065   // Creation information
00066   const nmethodScopes* _scopes;
00067   int                  _offset;
00068   char*                _pc;
00069 
00070  protected:
00071   // Cached information
00072   bool      _has_temps;
00073   bool      _has_context_temps;
00074   bool      _has_expr_stack;
00075   methodOop _method;
00076   int       _scopeID;
00077   bool      _lite;
00078   int       _senderScopeOffset;
00079   int       _senderByteCodeIndex;
00080   bool      _allocates_compiled_context;
00081   int       _name_desc_offset;
00082   int       _next;
00083 
00084   // If the pc of a scopeDesc is equal to invalid_pc, the scopeDesc is pc independent.
00085   // A pc independent scopeDesc prints out all the locations for its nameDescs.
00086   // NB: Only relevant for new backend.
00087   static char* invalid_pc;
00088 
00089  public:
00090   void iterate    (NameDescClosure* blk);       // info for given pc()
00091   void iterate_all(NameDescClosure* blk);       // info for all pc's
00092   
00093   NameDesc* nameDescAt(int& offset) const;
00094   int       valueAt(int& offset) const;
00095 
00096   ScopeDesc(const nmethodScopes* scopes, int offset, char* pc);
00097 
00098   int   offset() const                          { return int(_offset); }
00099   char* pc()     const                          { return _pc; } 
00100 
00101   bool is_equal(ScopeDesc* s) const {
00102     return    _scopes == s->_scopes
00103            && _offset == s->_offset;
00104   }
00105 
00106   // A lite scopeDesc has no information saved on temporaries or expression stack.
00107   bool          is_lite() const                 { return _lite; }
00108   bool          allocates_interpreted_context() const;
00109   methodOop     method() const                  { return _method; }
00110 
00111   // Tells whether a compiled context is allocated for this scope.
00112   bool          allocates_compiled_context() const { return _allocates_compiled_context; }
00113 
00114   // Returns the name desc for the allocated compiled context.
00115   NameDesc*     compiled_context();
00116 
00117   int           scopeID() const                 { return _scopeID; }
00118   const nmethodScopes* scopes() const           { return _scopes; }
00119   symbolOop     selector() const                { return method()->selector(); }
00120   ScopeDesc*    sender() const;
00121   virtual klassOop selfKlass() const            = 0;
00122 
00123   // Returns the parent scope
00124   // If cross_nmethod_boundary is false parent will return NULL if
00125   // the parent is located in another compilation unit (nmethod).
00126   virtual ScopeDesc* parent(bool cross_nmethod_boundary = false) const = 0;
00127   ScopeDesc* home(bool cross_nmethod_boundary = false) const;
00128   
00129   // Returns the bci of the calling method if this scopeDesc is inlined.
00130   // For a root scopeDesc IllegalBCI is returned.
00131   int senderBCI() const {
00132     assert(_senderByteCodeIndex != IllegalBCI,
00133            "need to ask calling byte code");
00134     return _senderByteCodeIndex; }
00135   
00136   // Root scope?
00137   bool isTop() const                            { return _senderScopeOffset == 0; }
00138 
00139   // Lookup key
00140   virtual LookupKey* key() const                = 0;
00141 
00142   // scope equivalence -- for compiler
00143   virtual bool s_equivalent(ScopeDesc* s) const;
00144   virtual bool l_equivalent(LookupKey* s) const;
00145   
00146   // types test operations
00147   virtual bool isMethodScope() const            { return false; }
00148   virtual bool isBlockScope() const             { return false; }
00149   virtual bool isTopLevelBlockScope() const     { return false; }
00150   virtual bool isNonInlinedBlockScope() const   { return false; }
00151 
00152   virtual NameDesc* self() const                = NULL;
00153   NameDesc* temporary       (int index, bool canFail = false);
00154   NameDesc* contextTemporary(int index, bool canFail = false);
00155   NameDesc* exprStackElem   (int bci, bool includeTrivial = true);
00156 
00157  public:
00158   int next_offset() const                       { return _next; } 
00159   int sender_scope_offset() const               { return _offset - _senderScopeOffset; }
00160 
00161   bool verify();
00162   void verify_expression_stack(int bci);
00163 
00164   // printing support
00165   void print(int indent, bool all_pcs);         // print info for current/all pc's
00166   void print()                                  { print(0, false); }
00167   virtual void print_value_on(outputStream* st) const;
00168 
00169  protected:
00170   virtual bool shallow_verify()                 { return true; }
00171   virtual void printName() = 0;
00172   virtual void printSelf() {}
00173 
00174  public:
00175   Expr* selfExpr(PReg* p) const;                // Type information for the optimizing compiler
00176 
00177   friend nmethodScopes;
00178   friend NonInlinedBlockScopeDesc;
00179 };
00180 
00181 
00182 class MethodScopeDesc : public ScopeDesc {
00183  protected:
00184   // Cached information
00185   LookupKey _key;
00186   NameDesc* _self_name;
00187 
00188  public:
00189   MethodScopeDesc(const nmethodScopes* scopes, int offset, char* pc); 
00190   bool s_equivalent(ScopeDesc* s) const;
00191   bool l_equivalent(LookupKey* s) const;
00192 
00193   bool isMethodScope() const                    { return true; }
00194 
00195   NameDesc* self() const                        { return _self_name; }
00196   LookupKey* key() const                        { return (LookupKey*)&_key; }
00197   klassOop selfKlass() const                    { return _key.klass(); }
00198 
00199   ScopeDesc* parent(bool cross_nmethod_boundary = false) const { return NULL; }
00200   
00201   // printing support
00202   void printName();
00203   void printSelf();
00204   void print_value_on(outputStream* st) const;
00205 };
00206 
00207 // an inlined block whose parent scope is in the same nmethod
00208 class BlockScopeDesc : public ScopeDesc {
00209  protected:
00210   // Cached information
00211   int _parentScopeOffset;
00212 
00213  public:
00214   BlockScopeDesc(const nmethodScopes* scopes, int offset, char* pc);
00215  
00216   // NB: the next three operations may return NULL (no context)
00217   klassOop   selfKlass() const;         
00218   NameDesc*  self() const;
00219   ScopeDesc* parent(bool cross_nmethod_boundary = false) const;
00220 
00221   LookupKey* key() const;
00222   
00223   bool s_equivalent(ScopeDesc* s) const;
00224 
00225   bool isBlockScope() const                     { return true; }
00226   
00227   // print operations
00228   void printSelf();
00229   void printName();
00230   void print_value_on(outputStream* st) const;
00231 };
00232 
00233 // A block method whose enclosing scope isn't in the same nmethod.
00234 // Must be a root scope.
00235 class TopLevelBlockScopeDesc : public ScopeDesc {
00236  protected:
00237   // Cached information
00238   NameDesc* _self_name;
00239   klassOop  _self_klass;
00240 
00241  public:
00242   TopLevelBlockScopeDesc(const nmethodScopes* scopes, int offset, char* pc);
00243 
00244   // type test operations
00245   bool isBlockScope() const                     { return true; }
00246   bool isTopLevelBlockScope() const             { return true; }
00247 
00248   klassOop selfKlass() const                    { return _self_klass; }
00249   NameDesc* self() const                        { return _self_name; }
00250   // NB: parent() may return NULL for clean blocks 
00251   ScopeDesc* parent(bool cross_nmethod_boundary = false) const; 
00252 
00253   LookupKey* key() const;
00254   
00255   bool s_equivalent(ScopeDesc* s) const;
00256 
00257   // print operations
00258   void printSelf();
00259   void printName();
00260   void print_value_on(outputStream* st) const;
00261 };
00262 
00263 class NonInlinedBlockScopeDesc : public PrintableResourceObj {
00264  protected:
00265   // Creation information
00266   const nmethodScopes* _scopes;
00267   int                  _offset;
00268 
00269  protected:
00270   // Cached information
00271   methodOop _method;
00272   int       _parentScopeOffset;
00273   
00274  public:
00275   NonInlinedBlockScopeDesc(const nmethodScopes* scopes, int offset);
00276 
00277   methodOop  method() const { return _method; }
00278   ScopeDesc* parent() const;
00279   void       print();
00280 };
00281 
00282 #endif

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