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/_scopeDesc.cpp.incl"
00029
00030 char* ScopeDesc::invalid_pc = (char*) -1;
00031
00032 int compareBCI(int bci1, int bci2) {
00033 assert(bci1 != IllegalBCI && bci2 != IllegalBCI, "can't compare");
00034 return bci1 - bci2;
00035 }
00036
00037 ScopeDesc::ScopeDesc(const nmethodScopes* scopes, int offset, char* pc) {
00038 _scopes = scopes;
00039 _offset = offset;
00040 _pc = pc;
00041
00042 _name_desc_offset = offset;
00043
00044 scopeDescHeaderByte b;
00045 b.unpack(_scopes->get_next_char(_name_desc_offset));
00046
00047 _lite = b.is_lite();
00048 _has_temps = b.has_temps();
00049 _has_context_temps = b.has_context_temps();
00050 _has_expr_stack = b.has_expr_stack();
00051
00052 assert(offset != 0 || !is_lite(), "Root scopeDesc cannot be lite");
00053
00054 if (b.has_nameDescs()) {
00055 _next = _scopes->unpackValueAt(_name_desc_offset) + _offset;
00056 } else {
00057 _next = -1;
00058 }
00059
00060 if (_offset == 0) {
00061 _senderScopeOffset = 0;
00062 _senderByteCodeIndex = IllegalBCI;
00063 } else {
00064 _senderScopeOffset = _scopes->unpackValueAt(_name_desc_offset);
00065 _senderByteCodeIndex = _scopes->unpackValueAt(_name_desc_offset);
00066 }
00067 _method = methodOop(_scopes->unpackOopAt(_name_desc_offset));
00068 assert(_method->is_method(), "expecting a method");
00069 _allocates_compiled_context = b.has_compiled_context();
00070 _scopeID = _scopes->unpackValueAt(_name_desc_offset);
00071 }
00072
00073
00074 ScopeDesc* ScopeDesc::home(bool cross_nmethod_boundary ) const {
00075 ScopeDesc* p = (ScopeDesc*)this;
00076 for ( ; p && !p->isMethodScope(); p = p->parent(cross_nmethod_boundary)) ;
00077 return p;
00078 }
00079
00080
00081 NameDesc* ScopeDesc::temporary(int index, bool canFail) {
00082 int pos = _name_desc_offset;
00083 NameDesc* result = NULL;
00084 if (_has_temps) {
00085 NameDesc* current = nameDescAt(pos);
00086 int i = 0;
00087 while (current != NULL) {
00088 if (i == index) { result = current; break; }
00089 current = nameDescAt(pos);
00090 i++;
00091 }
00092 }
00093 if (!result && !canFail) fatal1("couldn't find temporary %d", index);
00094 return result;
00095 }
00096
00097
00098 NameDesc* ScopeDesc::contextTemporary(int index, bool canFail) {
00099 int pos = _name_desc_offset;
00100 NameDesc* result = NULL;
00101 if (_has_temps) {
00102 NameDesc* current = nameDescAt(pos);
00103 while(current) {
00104 current = nameDescAt(pos);
00105 }
00106 }
00107 if (_has_context_temps) {
00108 NameDesc* current = nameDescAt(pos);
00109 int i = 0;
00110 while(current) {
00111 if (i == index) { result = current; break; }
00112 current = nameDescAt(pos);
00113 i++;
00114 }
00115 }
00116 if (!result && !canFail) fatal1("couldn't find context temporary %d", index);
00117 return result;
00118 }
00119
00120
00121 NameDesc* ScopeDesc::exprStackElem(int bci, bool includeTrivial) {
00122 int pos = _name_desc_offset;
00123 if (_has_temps) {
00124 NameDesc* current = nameDescAt(pos);
00125 while(current) {
00126 current = nameDescAt(pos);
00127 }
00128 }
00129 if (_has_context_temps) {
00130 NameDesc* current = nameDescAt(pos);
00131 while(current) {
00132 current = nameDescAt(pos);
00133 }
00134 }
00135 if (_has_expr_stack) {
00136 NameDesc* current = nameDescAt(pos);
00137 while(current) {
00138 int the_bci = valueAt(pos);
00139 if (bci == the_bci) return current;
00140 current = nameDescAt(pos);
00141 }
00142 }
00143 return NULL;
00144 }
00145
00146
00147 void ScopeDesc::iterate(NameDescClosure* blk) {
00148 int pos = _name_desc_offset;
00149 if (_has_temps) {
00150 NameDesc* current = nameDescAt(pos);
00151 int number = 0;
00152 while(current) {
00153 blk->temp(number++, current, pc());
00154 current = nameDescAt(pos);
00155 }
00156 }
00157 if (_has_context_temps) {
00158 NameDesc* current = nameDescAt(pos);
00159 int number = 0;
00160 while(current) {
00161 blk->context_temp(number++, current, pc());
00162 current = nameDescAt(pos);
00163 }
00164 }
00165 if (_has_expr_stack) {
00166 NameDesc* current = nameDescAt(pos);
00167 while(current) {
00168 blk->stack_expr(valueAt(pos), current, pc());
00169 current = nameDescAt(pos);
00170 }
00171 }
00172 }
00173
00174
00175
00176
00177
00178 class IterationHelper: public UnpackClosure {
00179 protected:
00180 int _no;
00181 NameDescClosure* _blk;
00182 bool _is_used;
00183
00184 void use() { _is_used = true; }
00185
00186 public:
00187 void init(int no, NameDescClosure* blk) {
00188 _no = no;
00189 _blk = blk;
00190 _is_used = false;
00191 }
00192
00193 bool is_used() const { return _is_used; }
00194 };
00195
00196 class IH_arg : public IterationHelper { void nameDescAt(NameDesc* nd, char* pc) { use(); _blk->arg (_no, nd, pc); } };
00197 class IH_temp : public IterationHelper { void nameDescAt(NameDesc* nd, char* pc) { use(); _blk->temp (_no, nd, pc); } };
00198 class IH_context_temp: public IterationHelper { void nameDescAt(NameDesc* nd, char* pc) { use(); _blk->context_temp(_no, nd, pc); } };
00199 class IH_stack_expr : public IterationHelper { void nameDescAt(NameDesc* nd, char* pc) { use(); _blk->stack_expr (_no, nd, pc); } };
00200
00201
00202
00203 void ScopeDesc::iterate_all(NameDescClosure* blk) {
00204 int pos = _name_desc_offset;
00205 if (_has_temps) {
00206 int no = 0;
00207 IH_temp helper;
00208 do {
00209 helper.init(no++, blk);
00210 _scopes->iterate(pos, &helper);
00211 } while (helper.is_used());
00212 }
00213 if (_has_context_temps) {
00214 int no = 0;
00215 IH_context_temp helper;
00216 do {
00217 helper.init(no++, blk);
00218 _scopes->iterate(pos, &helper);
00219 } while (helper.is_used());
00220 }
00221 if (_has_expr_stack) {
00222 int no = 0;
00223 IH_stack_expr helper;
00224 do {
00225 helper.init(no++, blk);
00226 _scopes->iterate(pos, &helper);
00227 if (helper.is_used()) valueAt(pos);
00228 } while (helper.is_used());
00229 }
00230 }
00231
00232
00233 bool ScopeDesc::allocates_interpreted_context() const {
00234 return method()->allocatesInterpretedContext();
00235 }
00236
00237
00238 NameDesc* ScopeDesc::compiled_context() {
00239 assert(allocates_compiled_context(), "must allocate a context");
00240 const int temporary_index_for_context = 0;
00241 return temporary(temporary_index_for_context);
00242 }
00243
00244
00245 bool ScopeDesc::s_equivalent(ScopeDesc* s) const {
00246 return method() == s->method()
00247 && (_senderByteCodeIndex == s->_senderByteCodeIndex ||
00248 _senderByteCodeIndex < 0 || s->_senderByteCodeIndex < 0);
00249
00250 }
00251
00252
00253 bool ScopeDesc::l_equivalent(LookupKey* l) const {
00254 return selector() == l->selector();
00255 }
00256
00257
00258 ScopeDesc* ScopeDesc::sender() const {
00259 return _senderScopeOffset ? _scopes->at(_offset - _senderScopeOffset, pc()) : NULL;
00260 }
00261
00262
00263 NameDesc* ScopeDesc::nameDescAt(int& offset) const {
00264 return _scopes->unpackNameDescAt(offset, pc());
00265 }
00266
00267
00268 int ScopeDesc::valueAt(int& offset) const {
00269 return _scopes->unpackValueAt(offset);
00270 }
00271
00272
00273 bool ScopeDesc::verify() {
00274
00275 bool ok = true;
00276
00277
00278 ScopeDesc* s = sender();
00279 if (s && !s->shallow_verify()) {
00280 std->print("invalid sender %#lx of ScopeDesc %#lx", s, this);
00281 ok = false;
00282 }
00283 ScopeDesc* p = parent();
00284 if (p && !p->shallow_verify()) {
00285 std->print("invalid parent %#lx of ScopeDesc %#lx", p, this);
00286 ok = false;
00287 }
00288 return ok;
00289 }
00290
00291
00292
00293 void ScopeDesc::verify_expression_stack(int bci) {
00294 GrowableArray<int>* mapping = method()->expression_stack_mapping(bci);
00295 for (int index = 0; index < mapping->length(); index++) {
00296 NameDesc* nd = exprStackElem(mapping->at(index));
00297 if (nd == NULL) { warning("expression not found in nmethod"); continue; }
00298
00299
00300
00301
00302
00303 }
00304 }
00305
00306
00307 class PrintNameDescClosure: public NameDescClosure {
00308 private:
00309 int _indent;
00310 char* _pc0;
00311
00312 void print(char* title, int no, NameDesc* nd, char* pc) {
00313 std->fill_to(_indent);
00314 if (UseNewBackend) {
00315 std->print("%5d: ", pc - _pc0);
00316 }
00317 std->print("%s[%d]\t", title, no); nd->print(); std->cr();
00318 }
00319
00320 public:
00321 PrintNameDescClosure(int indent, char* pc0) { _indent = indent; _pc0 = pc0; }
00322
00323 void arg (int no, NameDesc* a, char* pc) { print("arg ", no, a, pc); }
00324 void temp (int no, NameDesc* t, char* pc) { print("temp ", no, t, pc); }
00325 void context_temp(int no, NameDesc* c, char* pc) { print("c_temp", no, c, pc); }
00326 void stack_expr (int no, NameDesc* e, char* pc) { print("expr ", no, e, pc); }
00327 };
00328
00329
00330 void ScopeDesc::print(int indent, bool all_pcs) {
00331 std->fill_to(indent);
00332 printName();
00333 std->print("ScopeDesc @%d%s: ", offset(), is_lite() ? ", lite" : "");
00334 std->print(" (ID %ld) ", scopeID());
00335 method()->selector()->print_symbol_on();
00336 std->print(" %#x", method());
00337 std->cr();
00338 ScopeDesc* s = sender();
00339 if (s != NULL) {
00340 std->fill_to(indent);
00341 std->print("sender: (%d) @ %ld", s->offset(), long(senderBCI()));
00342 }
00343 ScopeDesc* p = parent();
00344 if (p != NULL) {
00345 if (s != NULL) {
00346 std->print("; ");
00347 } else {
00348 std->fill_to(indent);
00349 }
00350 std->print("parent: (%d)", p->offset());
00351 }
00352 if (s != NULL || p != NULL) {
00353 std->cr();
00354 }
00355 std->fill_to(indent);
00356 printSelf();
00357 PrintNameDescClosure blk(indent+2, _scopes->my_nmethod()->insts());
00358 if (all_pcs) {
00359 iterate_all(&blk);
00360 } else {
00361 iterate(&blk);
00362 }
00363 }
00364
00365
00366 void ScopeDesc::print_value_on(outputStream* st) const {
00367
00368 if (WizardMode)
00369 st->print(" [%d]", offset());
00370 }
00371
00372
00373 bool MethodScopeDesc::s_equivalent(ScopeDesc* s) const {
00374 return s->isMethodScope()
00375 && ScopeDesc::s_equivalent(s)
00376 && key()->equal(((MethodScopeDesc*)s)->key());
00377 }
00378
00379
00380 bool MethodScopeDesc::l_equivalent(LookupKey* l) const {
00381 return ScopeDesc::l_equivalent(l) && selfKlass() == l->klass();
00382 }
00383
00384
00385 MethodScopeDesc::MethodScopeDesc(const nmethodScopes* scopes, int offset, char* pc)
00386 : ScopeDesc(scopes, offset, pc), _key() {
00387 oop k = _scopes->unpackOopAt(_name_desc_offset);
00388 oop s = _scopes->unpackOopAt(_name_desc_offset);
00389 _key.initialize((klassOop) k, s);
00390 _self_name = _scopes->unpackNameDescAt(_name_desc_offset, pc);
00391 if (_next == -1) _next = _name_desc_offset;
00392 }
00393
00394
00395 void MethodScopeDesc::printName() {
00396 std->print("Method");
00397 }
00398
00399
00400 void MethodScopeDesc::printSelf() {
00401 printIndent();
00402 std->print("self: ");
00403 self()->print();
00404 std->cr();
00405 }
00406
00407
00408 void MethodScopeDesc::print_value_on(outputStream* st) const {
00409 key()->print_on(st);
00410 ScopeDesc::print_value_on(st);
00411 }
00412
00413
00414 void BlockScopeDesc::printSelf() {
00415 ScopeDesc::printSelf();
00416 std->cr();
00417 }
00418
00419
00420 BlockScopeDesc::BlockScopeDesc(const nmethodScopes* scopes, int offset, char* pc)
00421 : ScopeDesc(scopes, offset, pc) {
00422 _parentScopeOffset = _scopes->unpackValueAt(_name_desc_offset);
00423 if (_next == -1) _next = _name_desc_offset;
00424 }
00425
00426
00427 bool BlockScopeDesc::s_equivalent(ScopeDesc* s) const {
00428 return s->isBlockScope() && ScopeDesc::s_equivalent(s);
00429 }
00430
00431
00432 void BlockScopeDesc::printName() {
00433 std->print("Block");
00434 }
00435
00436
00437 klassOop BlockScopeDesc::selfKlass() const {
00438 ScopeDesc* p = parent();
00439 return p ? p->selfKlass() : NULL;
00440 }
00441
00442
00443 NameDesc* BlockScopeDesc::self() const {
00444 ScopeDesc* p = parent();
00445 return p ? p->self() : NULL;
00446 }
00447
00448
00449 ScopeDesc* BlockScopeDesc::parent(bool cross_nmethod_boundary) const {
00450 return _parentScopeOffset ? _scopes->at(_offset - _parentScopeOffset, pc()) : NULL;
00451 }
00452
00453
00454 void BlockScopeDesc::print_value_on(outputStream* st) const {
00455 st->print("block {parent %d}", _offset - _parentScopeOffset);
00456 ScopeDesc::print_value_on(st);
00457 }
00458
00459
00460 LookupKey* BlockScopeDesc::key() const {
00461 return LookupKey::allocate(selfKlass(), method());
00462 }
00463
00464
00465 LookupKey* TopLevelBlockScopeDesc::key() const {
00466 return LookupKey::allocate(selfKlass(), method());
00467 }
00468
00469
00470 NonInlinedBlockScopeDesc::NonInlinedBlockScopeDesc(const nmethodScopes* scopes, int offset) {
00471 _offset = offset;
00472 _scopes = scopes;
00473
00474 scopeDescHeaderByte b;
00475 b.unpack(_scopes->get_next_char(offset));
00476 _method = methodOop(scopes->unpackOopAt(offset));
00477 _parentScopeOffset = scopes->unpackValueAt(offset);
00478 }
00479
00480
00481 void NonInlinedBlockScopeDesc::print() {
00482 std->print("NonInlinedBlockScopeDesc\n");
00483 std->print(" - method: ");
00484 method()->print_value();
00485 std->cr();
00486 std->print(" - parent offset: %d\n", _parentScopeOffset);
00487 }
00488
00489
00490 ScopeDesc* NonInlinedBlockScopeDesc::parent() const {
00491 return _parentScopeOffset ? _scopes->at(_offset - _parentScopeOffset, ScopeDesc::invalid_pc) : NULL;
00492 }
00493
00494
00495 TopLevelBlockScopeDesc::TopLevelBlockScopeDesc(const nmethodScopes* scopes, int offset, char* pc)
00496 : ScopeDesc(scopes, offset, pc) {
00497 _self_name = _scopes->unpackNameDescAt(_name_desc_offset, pc);
00498 _self_klass = klassOop(scopes->unpackOopAt(_name_desc_offset));
00499 if (_next == -1) _next = _name_desc_offset;
00500 }
00501
00502
00503 void TopLevelBlockScopeDesc::printSelf() {
00504 ScopeDesc::printSelf();
00505 std->print("self: ");
00506 self()->print();
00507 std->cr();
00508 }
00509
00510
00511 ScopeDesc* TopLevelBlockScopeDesc::parent(bool cross_nmethod_boundary) const {
00512 if (!cross_nmethod_boundary) return NULL;
00513 nmethod* nm = _scopes->my_nmethod();
00514 int index;
00515 nmethod* parent = nm->jump_table_entry()->parent_nmethod(index);
00516 NonInlinedBlockScopeDesc* scope = parent->noninlined_block_scope_at(index);
00517 return scope->parent();
00518 }
00519
00520
00521 bool TopLevelBlockScopeDesc::s_equivalent(ScopeDesc* s) const {
00522
00523 return s->isBlockScope() && ScopeDesc::s_equivalent(s);
00524 }
00525
00526
00527 void TopLevelBlockScopeDesc::printName() {
00528 std->print("TopLevelBlock");
00529 }
00530
00531
00532 void TopLevelBlockScopeDesc::print_value_on(outputStream* st) const {
00533 st->print("top block");
00534 ScopeDesc::print_value_on(st);
00535 }
00536
00537
00538 Expr* ScopeDesc::selfExpr(PReg* p) const {
00539 klassOop self_klass = selfKlass();
00540 if (self_klass == trueObj->klass()) return new ConstantExpr(trueObj, p, NULL);
00541 if (self_klass == falseObj->klass()) return new ConstantExpr(falseObj, p, NULL);
00542 if (self_klass == nilObj->klass()) return new ConstantExpr(nilObj, p, NULL);
00543 return new KlassExpr(self_klass, p, NULL);
00544 }
00545
00546
00547 #endif
00548