00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef DELTA_COMPILER
00025
00026
00027
00028 class UnpackClosure: public StackObj {
00029 public:
00030 virtual void nameDescAt(NameDesc* nameDesc, char* pc) = 0;
00031 };
00032
00033
00034
00035
00036
00037
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
00048
00049 uint16 _oops_offset;
00050 uint16 _value_offset;
00051 uint16 _pcs_offset;
00052 int _dependants_end;
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
00069 u_char* start() const { return (u_char*) (this+1); }
00070
00071 public:
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
00116 ScopeDesc* end() const { return (ScopeDesc*) (start() + length()); }
00117
00118 bool includes(ScopeDesc* d) const { return this == d->_scopes; }
00119
00120
00121
00122 ScopeDesc *root() const { return at(0, ScopeDesc::invalid_pc); }
00123
00124 int size() const { return sizeof(nmethodScopes) + length(); }
00125
00126
00127 ScopeDesc* at(int offset, char* pc) const;
00128
00129 NonInlinedBlockScopeDesc* noninlined_block_scope_at(int offset) const ;
00130
00131
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;
00151 NameDesc* unpackNameDescAt(int& offset, char* pc) const;
00152
00153 private:
00154 NameDesc* unpackNameDescAt(int& offset, bool& is_last, char* pc) const;
00155 public:
00156
00157
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
00170 void print_partition();
00171 };
00172
00173
00174 #endif