00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025
00026 #ifdef DELTA_COMPILER
00027
00028 # include "incls/_nmethodScopes.cpp.incl"
00029
00030 ScopeDesc* nmethodScopes::at(int offset, char* pc) const {
00031
00032 assert(offset >= 0, "illegal desc offset");
00033 scopeDescHeaderByte b;
00034 b.unpack(peek_next_char(offset));
00035 switch (b.code()) {
00036 case METHOD_CODE : return new MethodScopeDesc( (nmethodScopes*) this, offset, pc);
00037 case TOPLEVELBLOCK_CODE : return new TopLevelBlockScopeDesc((nmethodScopes*) this, offset, pc);
00038 case BLOCK_CODE : return new BlockScopeDesc( (nmethodScopes*) this, offset, pc);
00039 case NONINLINED_BLOCK_CODE: return NULL;
00040 }
00041 fatal("Unknown ScopeDesc code in nmethodScopes");
00042 return NULL;
00043 }
00044
00045
00046 NonInlinedBlockScopeDesc* nmethodScopes::noninlined_block_scope_at(int offset) const {
00047
00048 assert(offset > 0, "illegal desc offset");
00049 scopeDescHeaderByte b;
00050 b.unpack(peek_next_char(offset));
00051 if ( b.code() != NONINLINED_BLOCK_CODE) {
00052 fatal("Not an noninlined scope desc as expected");
00053 }
00054 return new NonInlinedBlockScopeDesc((nmethodScopes*)this, offset);
00055 }
00056
00057
00058 int16 nmethodScopes::get_next_half(int& offset) const {
00059 int16 v;
00060 v = get_next_char(offset) << BYTE_WIDTH;
00061 v = addBits(v, get_next_char(offset));
00062 return v;
00063 }
00064
00065
00066 inline u_char nmethodScopes::getIndexAt(int& offset) const {
00067 return get_next_char(offset);
00068 }
00069
00070
00071 inline oop nmethodScopes::unpackOopFromIndex(u_char index, int& offset) const {
00072 if (index == 0) return 0;
00073 if (index < EXTENDED_INDEX) return oop_at(index-1);
00074 return oop_at(get_next_half(offset)-1);
00075 }
00076
00077
00078 inline int nmethodScopes::unpackValueFromIndex(u_char index, int& offset) const {
00079 if (index <= MAX_INLINE_VALUE) return index;
00080 if (index < EXTENDED_INDEX) return value_at(index-(MAX_INLINE_VALUE+1));
00081 return value_at(get_next_half(offset)-(MAX_INLINE_VALUE+1));
00082 }
00083
00084
00085 oop nmethodScopes::unpackOopAt(int& offset) const {
00086 u_char index = getIndexAt(offset);
00087 return unpackOopFromIndex(index, offset);
00088 }
00089
00090
00091 int nmethodScopes::unpackValueAt(int& offset) const {
00092 u_char index = getIndexAt(offset);
00093 return unpackValueFromIndex(index, offset);
00094 }
00095
00096
00097 NameDesc* nmethodScopes::unpackNameDescAt(int& offset, bool& is_last, char* pc) const {
00098 int startOffset = offset;
00099 nameDescHeaderByte b;
00100 b.unpack(get_next_char(offset));
00101 is_last = b.is_last();
00102 NameDesc* nd;
00103 if (b.is_illegal()) {
00104 nd = new IllegalNameDesc;
00105 } else if (b.is_termination()) {
00106 return NULL;
00107 } else {
00108 u_char index;
00109 index = b.has_index() ? b.index() : getIndexAt(offset);
00110
00111 switch(b.code()) {
00112 case LOCATION_CODE: {
00113 Location l = Location(unpackValueFromIndex(index, offset));
00114 nd = new LocationNameDesc(l);
00115 break;
00116 }
00117 case VALUE_CODE: {
00118 oop v = unpackOopFromIndex(index, offset);
00119 nd = new ValueNameDesc(v);
00120 break;
00121 }
00122 case BLOCKVALUE_CODE: {
00123 oop blkMethod = unpackOopFromIndex(index, offset);
00124 assert(blkMethod->is_method(), "must be a method");
00125 int parent_scope_offset = unpackValueAt(offset);
00126 ScopeDesc* parent_scope = at(parent_scope_offset, pc);
00127 nd = new BlockValueNameDesc(methodOop(blkMethod), parent_scope);
00128 break;
00129 }
00130 case MEMOIZEDBLOCK_CODE: {
00131 Location l = Location(unpackValueFromIndex(index, offset));
00132 oop blkMethod = unpackOopAt(offset);
00133 assert(blkMethod->is_method(), "must be a method");
00134 int parent_scope_offset = unpackValueAt(offset);
00135 ScopeDesc* parent_scope = at(parent_scope_offset, pc);
00136 nd = new MemoizedBlockNameDesc(l, methodOop(blkMethod), parent_scope);
00137 break;
00138 }
00139 default:
00140 fatal1("no such name desc (code %d)", b.code());
00141 }
00142 }
00143 nd->offset = startOffset;
00144 return nd;
00145 }
00146
00147
00148 void nmethodScopes::iterate(int& offset, UnpackClosure* closure) const {
00149 char* pc = my_nmethod()->insts();
00150 bool is_last;
00151 NameDesc* nd = unpackNameDescAt(offset, is_last, ScopeDesc::invalid_pc);
00152 if (nd == NULL) return;
00153 closure->nameDescAt(nd, pc);
00154 while (!is_last) {
00155 nd = unpackNameDescAt(offset, is_last, ScopeDesc::invalid_pc);
00156 pc += unpackValueAt(offset);
00157 closure->nameDescAt(nd, pc);
00158 }
00159 }
00160
00161
00162 NameDesc* nmethodScopes::unpackNameDescAt(int& offset, char* pc) const {
00163 int pc_offset = pc - my_nmethod()->insts();
00164 int current_pc_offset = 0;
00165 bool is_last;
00166 NameDesc* result = unpackNameDescAt(offset, is_last, pc);
00167 if (result == NULL) return NULL;
00168 while (!is_last) {
00169 NameDesc* current = unpackNameDescAt(offset, is_last, pc);
00170 current_pc_offset += unpackValueAt(offset);
00171 if (current_pc_offset <= pc_offset) {
00172 result = current;
00173 }
00174 }
00175 return result;
00176 }
00177
00178
00179 # define FOR_EACH_OOPADDR(VAR) \
00180 for (oop* VAR = oops(), *CONC(VAR, _end) = oops() + oops_size(); \
00181 VAR < CONC(VAR, _end); VAR++)
00182
00183
00184 void nmethodScopes::verify() {
00185
00186 FOR_EACH_OOPADDR(addr) {
00187 VERIFY_TEMPLATE(addr)
00188 }
00189
00190
00191 FOR_EACH_SCOPE(this, s) {
00192 if (!s->verify())
00193 lprintf("\t\tin nmethod at %#lx (scopes)\n", my_nmethod());
00194 }
00195 }
00196
00197
00198 void nmethodScopes::scavenge_contents() {
00199 FOR_EACH_OOPADDR(addr) {
00200 SCAVENGE_TEMPLATE(addr);
00201 }
00202 }
00203
00204
00205 void nmethodScopes::switch_pointers(oop from, oop to,
00206 GrowableArray<nmethod*> *nmethods_to_invalidate) {
00207 Unused(to);
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 # ifdef NOT_IMPLEMENTED
00238 if (my_nmethod()->isInvalid()) return;
00239
00240 FOR_EACH_OOPADDR(addr) {
00241 if (*addr == from) {
00242 nmethods_to_invalidate->append(my_nmethod());
00243 return;
00244 }
00245 }
00246 # endif
00247 }
00248
00249
00250 void nmethodScopes::oops_do(void f(oop*)) {
00251 oop* end = oops() + oops_size();
00252 for (oop* p = oops(); p < end; p++) {
00253 f(p);
00254 }
00255 }
00256
00257
00258 void nmethodScopes::relocate() {
00259 FOR_EACH_OOPADDR(addr) {
00260 RELOCATE_TEMPLATE(addr);
00261 }
00262 }
00263
00264
00265 bool nmethodScopes::is_new() const {
00266 bool result = false;
00267 FOR_EACH_OOPADDR(addr) {
00268 if ((*addr)->is_new()) return true;
00269 }
00270 return false;
00271 }
00272
00273
00274 void nmethodScopes::print() {
00275 ResourceMark m;
00276 printIndent();
00277 lprintf("scopes:\n");
00278 Indent ++;
00279 FOR_EACH_SCOPE(this, d)
00280 d->print();
00281 Indent --;
00282 }
00283
00284
00285 void nmethodScopes::print_partition() {
00286 int d_size = dependent_length() * sizeof(oop);
00287 int o_size = oops_size() * sizeof(oop) - d_size;
00288 int p_size = (int) pcsEnd() - (int) pcs();
00289 int v_size = value_size() * sizeof(int);
00290 int total = v_size + p_size + o_size + d_size;
00291
00292 std->print_cr("{deps %d%%, oops %d%%, bytes %d%%, pcs %d%%}",
00293 d_size * 100/ total,
00294 o_size * 100/ total,
00295 v_size * 100/ total,
00296 p_size * 100/ total);
00297 }
00298
00299 #endif