nmethodScopes.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996, LongView Technologies L.L.C. $Revision: 1.22 $ */
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 // UnpackClosure is used for iteration over a string of nameDescs with different pc values.
00027 
00028 class UnpackClosure: public StackObj {
00029  public:
00030   virtual void nameDescAt(NameDesc* nameDesc, char* pc) = 0;
00031 };
00032 
00033 
00034 // nmethodScopes represent the compressed nmethod source-level debugging information generated by the scopeDescRecorder.
00035 // Whenever the debugging information is needed, it is uncompressed into ScopeDescs.
00036 // Compression works mainly by putting all "large" data (e.g., oops) into an array and
00037 // using small (8-bit) indices to refer to this array from the actual scope data structures.
00038 
00039 # define FOR_EACH_SCOPE(SCOPES, VAR)\
00040    for(ScopeDesc* VAR = SCOPES->getNext(NULL); \
00041        VAR != NULL; VAR =  SCOPES->getNext(VAR) )
00042 
00043 class nmethodScopes : public ValueObj {
00044  private:
00045   int         _nmethod_offset; 
00046   uint16      _length;
00047   // Implements the compact version of nmethod scopes
00048   // with byte codes, shared oop array, and value array.
00049   uint16 _oops_offset;    // word offset to the oops array
00050   uint16 _value_offset;   // word offset to the value array
00051   uint16 _pcs_offset;     // word offset to PcDesc array
00052   int    _dependants_end; // size of dependants
00053 
00054  private:
00055   static uint16 pack_word_aligned(int value) {
00056     assert(value %  BytesPerWord == 0, "value should be word aligned");
00057     assert(value >> BytesPerWord <= nthMask(BitsPerByte*sizeof(uint16)),
00058            "value exceeds limit");
00059     return value >> LogBytesPerWord;
00060   }
00061 
00062   static int unpack_word_aligned(uint16 v) { return v << LogBytesPerWord; }
00063 
00064   int oops_offset()  const { return unpack_word_aligned(_oops_offset); }
00065   int value_offset() const { return unpack_word_aligned(_value_offset); }
00066   int pcs_offset()   const { return unpack_word_aligned(_pcs_offset); }
00067 
00068   // Return the address after the struct header
00069   u_char* start() const { return (u_char*) (this+1); }
00070 
00071  public: // for debugging
00072   oop* oops()      const  { return (oop*) (start() + oops_offset()); } 
00073   int  oops_size() const  { return (value_offset() - oops_offset())/sizeof(oop); }
00074   oop  oop_at(int index) const { 
00075     assert( index < oops_size(), "oops index out of range");
00076     return oops()[index]; 
00077   }
00078  private:
00079   int* values()     const { return (int*) (start() + value_offset()); } 
00080   int  value_size() const { return (pcs_offset() - value_offset())/sizeof(int); }
00081   int  value_at(int index) const {
00082     assert( index < value_size(), "oops index out of range");
00083     return values()[index]; 
00084   }
00085 
00086   inline u_char getIndexAt(int& offset) const;
00087   inline oop    unpackOopFromIndex(u_char index, int& offset) const;
00088   inline int  unpackValueFromIndex(u_char index, int& offset) const;
00089 
00090  private:
00091   friend class ScopeDescRecorder;
00092   void set_nmethod_offset(int v) { _nmethod_offset  = v; }
00093   void set_length(int v)         { _length          = pack_word_aligned(v); }
00094   void set_oops_offset(int v)    { _oops_offset     = pack_word_aligned(v); }
00095   void set_value_offset(int v)   { _value_offset    = pack_word_aligned(v); }
00096   void set_pcs_offset(int v)     { _pcs_offset      = pack_word_aligned(v); }
00097   void set_dependants_end(int v) { _dependants_end  = v; }
00098 
00099  public:
00100   klassOop dependant_at(int index) const {
00101     assert(index >= 0 && index < dependent_length(), "must be within bounds");
00102     oop result = oop_at(index);
00103     assert(result->is_klass(), "must be klass");
00104     return klassOop(result);
00105   }
00106   int dependent_length() const { return _dependants_end; }
00107 
00108   void* pcs()    const { return (void*) (start() + pcs_offset()); }
00109   void* pcsEnd() const { return (void*) end(); }
00110 
00111   int length()   const { return unpack_word_aligned(_length); }
00112 
00113   nmethod* my_nmethod() const { return (nmethod*) (((char*) this) - _nmethod_offset); };
00114 
00115   // returns the address following this nmethodScopes.
00116   ScopeDesc* end() const {  return (ScopeDesc*) (start()  + length()); }
00117 
00118   bool includes(ScopeDesc* d) const {  return this == d->_scopes; }
00119 
00120   // Returns the root scope without pc specific information.
00121   // The returned scope cannot be used for retrieving name desc information. 
00122   ScopeDesc *root() const { return at(0, ScopeDesc::invalid_pc); }
00123 
00124   int size() const { return sizeof(nmethodScopes) + length(); }
00125 
00126   // Returns a scope located at offset.
00127   ScopeDesc* at(int offset, char* pc) const;
00128 
00129   NonInlinedBlockScopeDesc* noninlined_block_scope_at(int offset) const ;
00130 
00131   // used in iterator macro FOR_EACH_SCOPE
00132   ScopeDesc *getNext(ScopeDesc *s) const {
00133     if (!s) return root();
00134     int offset = s->next_offset();
00135 
00136     if (offset + (sizeof(int) - (offset%sizeof(int))) % sizeof(int)
00137         >= (_oops_offset)*sizeof(oop)) return NULL;
00138     return at(offset, ScopeDesc::invalid_pc);
00139   }
00140 
00141   u_char get_next_char(int& offset) const { return *(start() + offset++); }
00142 
00143   int16  get_next_half(int& offset) const;
00144 
00145   u_char peek_next_char(int offset) const  { return *(start() + offset); }
00146 
00147   oop   unpackOopAt(int& offset) const;
00148   int unpackValueAt(int& offset) const;
00149 
00150   void iterate(int& offset, UnpackClosure* closure) const;      // iterates over a string of NameDescs (iterator is not called at termination)
00151   NameDesc* unpackNameDescAt(int& offset, char* pc) const;      // Unpacks a string of name descs and returns one matching the pc
00152 
00153  private:
00154   NameDesc* unpackNameDescAt(int& offset, bool& is_last, char* pc) const;       // Unpacks a single name desc at offset
00155  public:
00156 
00157   // Support for garbage collection.
00158   void oops_do(void f(oop*));
00159   void scavenge_contents();
00160   void switch_pointers(oop from, oop to, GrowableArray<nmethod*>* nmethods_to_invalidate);
00161 
00162   bool is_new() const;
00163 
00164   void relocate();
00165 
00166   void verify();
00167   void print();
00168 
00169   // Prints (dep d% oops %d bytes %d pcs %d)
00170   void print_partition();
00171 };
00172 
00173 
00174 #endif

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