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 # include "incls/_scope.cpp.incl"
00028 # include <string.h>
00029
00030 smi Scope::_currentScopeID;
00031
00032
00033
00034 SendInfo::SendInfo(InlinedScope* sen, LookupKey* lkup, Expr* r) {
00035 senderScope = sen;
00036 rcvr = r;
00037 sel = lkup->selector();
00038 key = lkup;
00039 init();
00040 }
00041
00042
00043 void SendInfo::computeNSends(RScope* rscope, int bci) {
00044 GrowableArray<RScope*>* lst = rscope->subScopes(bci);
00045 nsends = 0;
00046 for (int i = lst->length() - 1; i >= 0; i--) {
00047 nsends += lst->at(i)->nsends;
00048 }
00049 }
00050
00051 void SendInfo::init() {
00052 resReg = NULL; needRealSend = counting = false;
00053 nsends = -1; receiverStatic = predicted = uninlinable = false;
00054 inPrimFailure = senderScope && senderScope->gen()->in_prim_failure_block();
00055 }
00056
00057
00058
00059
00060 InlinedScope::InlinedScope() {}
00061
00062 void InlinedScope::initialize(methodOop method, klassOop methodHolder, InlinedScope* sender, RScope* rs, SendInfo* info) {
00063 _scopeID = currentScopeID();
00064 theCompiler->scopes->append(this);
00065 assert(theCompiler->scopes->at(_scopeID) == this, "bad list");
00066 _sender = sender;
00067 _scopeInfo = NULL;
00068 if (sender) {
00069 _senderBCI = sender->bci();
00070 sender->addSubScope(this);
00071 depth = _sender->depth + 1;
00072 loopDepth = _sender->loopDepth;
00073 } else {
00074 _senderBCI = IllegalBCI;
00075 depth = loopDepth = 0;
00076 }
00077 result = nlrResult = NULL;
00078 if (info && info->resReg) {
00079 resultPR = info->resReg;
00080 } else {
00081
00082 assert(isTop(), "should have resReg for inlined scope");
00083 resultPR = new SAPReg(this, resultLoc, false, false, PrologueBCI, EpilogueBCI);
00084 }
00085 rscope = rs;
00086 rs->extend();
00087
00088 predicted = info ? info->predicted : false;
00089
00090 assert(info->key->klass(), "must have klass");
00091 _key = info->key;
00092 _method = method;
00093 _methodHolder = methodHolder;
00094 _nofSends = 0;
00095 _nofInterruptPoints = 0;
00096 _primFailure = sender ? sender->_primFailure : false;
00097 _endsDead = false;
00098 _self = NULL;
00099 _gen.initialize(this);
00100
00101 _temporaries = NULL;
00102 _floatTemporaries = NULL;
00103 _contextTemporaries = NULL;
00104 _context = NULL;
00105 _exprStackElems = new GrowableArray<Expr*>(nofBytes());
00106 _subScopes = new GrowableArray<InlinedScope*>(5);
00107 _loops = new GrowableArray<CompiledLoop*>(5);
00108 _typeTests = new GrowableArray<NonTrivialNode*>(10);
00109
00110 _pregsBegSorted = new GrowableArray<PReg*>(5);
00111 _pregsEndSorted = new GrowableArray<PReg*>(5);
00112 _firstFloatIndex = -1;
00113 _hasBeenGenerated = false;
00114
00115 theCompiler->nofBytesCompiled(nofBytes());
00116 if (!rs->isNullScope() && rs->method() != method) {
00117
00118 rs = new RNullScope;
00119 }
00120 }
00121
00122 bool InlinedScope::isLite() const {
00123
00124
00125
00126 return GenerateLiteScopeDescs && (sender() != NULL) && (_nofInterruptPoints == 0);
00127 }
00128
00129 void MethodScope::initialize(methodOop method, klassOop methodHolder, InlinedScope* sen, RScope* rs, SendInfo* info) {
00130 InlinedScope::initialize(method, methodHolder, sen, rs, info);
00131 }
00132
00133
00134 MethodScope::MethodScope() {}
00135 BlockScope::BlockScope() {}
00136
00137
00138 void BlockScope::initialize(methodOop method, klassOop methodHolder, Scope* p, InlinedScope* s, RScope* rs, SendInfo* info) {
00139 InlinedScope::initialize(method, methodHolder, s, rs, info);
00140 _parent = p;
00141 _self_is_initialized = false;
00142 if (s == NULL) {
00143
00144
00145 _context = new SAPReg(this, PrologueBCI, EpilogueBCI);
00146 } else {
00147
00148
00149 switch (method->block_info()) {
00150 case methodOopDesc::expects_nil:
00151 _context = NULL; break;
00152 case methodOopDesc::expects_self:
00153 _context = self()->preg(); fatal("self not known yet -- fix this"); break;
00154 case methodOopDesc::expects_parameter:
00155 Unimplemented();
00156 break;
00157 case methodOopDesc::expects_context:
00158 if (p->isInlinedScope()) {
00159 _context = ((InlinedScope*)p)->context();
00160 } else {
00161 fatal("shouldn't inline");
00162 }
00163 break;
00164 default:
00165 fatal("unexpected incoming info");
00166 }
00167 }
00168 }
00169
00170
00171 MethodScope* MethodScope::new_MethodScope(methodOop method, klassOop methodHolder, InlinedScope* sen, RScope* rs, SendInfo* info) {
00172 MethodScope* new_scope = new MethodScope;
00173 new_scope->initialize(method, methodHolder, sen, rs, info);
00174 new_scope->initializeArguments();
00175 return new_scope;
00176 }
00177
00178
00179 BlockScope* BlockScope::new_BlockScope(methodOop method, klassOop methodHolder, Scope* p, InlinedScope* s, RScope* rs, SendInfo* info) {
00180 BlockScope* new_scope = new BlockScope;
00181 new_scope->initialize(method, methodHolder, p, s, rs, info);
00182 new_scope->initializeArguments();
00183 return new_scope;
00184 }
00185
00186
00187 void InlinedScope::addSubScope(InlinedScope* s) {
00188
00189
00190
00191
00192 _subScopes->append(s);
00193 }
00194
00195 void InlinedScope::subScopesDo(Closure<InlinedScope*>* f) {
00196 f->do_it(this);
00197 _subScopes->apply(f);
00198 }
00199
00200 MergeNode* InlinedScope::nlrTestPoint() {
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 if (!_nlrTestPoint) {
00224 int end_bci = nofBytes();
00225
00226
00227
00228
00229 _nlrTestPoint = NodeFactory::new_MergeNode(end_bci);
00230 _nlrTestPoint->append(NodeFactory::new_NLRTestNode(end_bci));
00231 }
00232 return _nlrTestPoint;
00233 }
00234
00235
00236 void InlinedScope::addResult(Expr* e) {
00237
00238 assert(e->preg() == resultPR || resultPR == NULL || e->isNoResultExpr(), "bad result PReg");
00239 if (result == NULL) {
00240 result = e;
00241 } else {
00242 result = result->mergeWith(e, result->node());
00243 }
00244 }
00245
00246
00247 void InlinedScope::initializeArguments() {
00248 const int nofArgs = _method->number_of_arguments();
00249 _arguments = new GrowableArray<Expr*>(nofArgs, nofArgs, NULL);
00250 if (isTop()) {
00251
00252
00253 _self =
00254 new KlassExpr(klassOop(selfKlass()),
00255 new SAPReg(this, unAllocated, false, false, PrologueBCI, EpilogueBCI),
00256 NULL);
00257
00258
00259 for (int i = 0; i < nofArgs; i++) {
00260 SAPReg* arg = new SAPReg(this, Mapping::incomingArg(i, nofArgs), false, false, PrologueBCI, EpilogueBCI);
00261 _arguments->at_put(i, new UnknownExpr(arg));
00262 }
00263 } else {
00264 _self = NULL;
00265
00266 const int top = sender()->exprStack()->length();
00267 for (int i = 0; i < nofArgs; i++) {
00268 _arguments->at_put(i, sender()->exprStack()->at(top - nofArgs + i));
00269 }
00270 }
00271 }
00272
00273
00274 void BlockScope::initializeSelf() {
00275
00276
00277
00278
00279
00280 if (_parent->isInlinedScope() && method()->hasNestedBlocks()) {
00281 _gen.set_self_via_context();
00282 }
00283 }
00284
00285
00286 void InlinedScope::createTemporaries(int nofTemps) {
00287
00288 int firstNew;
00289 if (!hasTemporaries()) {
00290
00291 _temporaries = new GrowableArray<Expr*>(nofTemps, nofTemps, NULL);
00292
00293
00294
00295 if (_context) {
00296 _temporaries->at_put(0, new ContextExpr(_context));
00297 firstNew = 1;
00298 } else {
00299 firstNew = 0;
00300 }
00301 } else {
00302
00303 const GrowableArray<Expr*>* oldTemps = _temporaries;
00304 const int n = nofTemps + oldTemps->length();
00305 _temporaries = new GrowableArray<Expr*>(n, n, NULL);
00306 firstNew = oldTemps->length();
00307 nofTemps += oldTemps->length();
00308 for (int i = 0; i < firstNew; i++) _temporaries->at_put(i, oldTemps->at(i));
00309 }
00310
00311 ConstPReg* nil = new_ConstPReg(this, nilObj);
00312 for (int i = firstNew; i < nofTemps; i++) {
00313 PReg* r = new PReg(this);
00314 _temporaries->at_put(i, new UnknownExpr(r, NULL));
00315 if (isTop()) {
00316
00317 } else {
00318 gen()->append(NodeFactory::new_AssignNode(nil, r));
00319 }
00320 }
00321 }
00322
00323
00324 void InlinedScope::createFloatTemporaries(int nofFloats) {
00325 assert(!hasFloatTemporaries(), "cannot be called twice");
00326 _floatTemporaries = new GrowableArray<Expr*>(nofFloats, nofFloats, NULL);
00327
00328 for (int i = 0; i < nofFloats; i++) {
00329 PReg* preg = new PReg(this, Location::floatLocation(scopeID(), i), false, false);
00330 _floatTemporaries->at_put(i, new UnknownExpr(preg, NULL));
00331 if (isTop()) {
00332
00333 } else {
00334 warning("float initialization of floats in inlined scopes not implemented yet");
00335 }
00336 }
00337 }
00338
00339
00340 void InlinedScope::createContextTemporaries(int nofTemps) {
00341
00342
00343
00344 assert(_contextTemporaries == NULL, "more than one context created");
00345 assert(allocatesInterpretedContext(), "inconsistent context info");
00346 _contextTemporaries = new GrowableArray<Expr*>(nofTemps, nofTemps, NULL);
00347 for (int i = 0; i < nofTemps; i++) {
00348 PReg* r = new PReg(this);
00349 _contextTemporaries->at_put(i, new UnknownExpr(r, NULL));
00350 }
00351
00352 if (_context == NULL) {
00353
00354
00355
00356
00357 assert(isMethodScope() || isBlockScope() && method()->block_info() == methodOopDesc::expects_nil, "check this");
00358
00359 _context = new SAPReg(this, PrologueBCI, EpilogueBCI);
00360 }
00361
00362
00363
00364 _temporaries->at_put(0, new ContextExpr(_context));
00365 }
00366
00367 void InlinedScope::contextTemporariesAtPut(int no, Expr* e) {
00368 assert(!e->preg()->isSAPReg() || e->preg()->isBlockPReg() || ((SAPReg*)e->preg())->isInContext(), "not in context");
00369 _contextTemporaries->at_put(no, e);
00370 }
00371
00372
00373 bool InlinedScope::allocatesCompiledContext() const {
00374 if (!allocatesInterpretedContext()) return false;
00375 ContextCreateNode* c = _contextInitializer->creator();
00376 if (bbIterator->usesBuilt && c->deleted) {
00377
00378 return false;
00379 } else {
00380 return true;
00381 }
00382 }
00383
00384
00385 void InlinedScope::prologue() {
00386 theCompiler->enterScope(this);
00387 initializeSelf();
00388 }
00389
00390
00391 static int compare_scopeBCIs(InlinedScope** a, InlinedScope** b) {
00392
00393 if ((*a)->hasBeenGenerated() == (*b)->hasBeenGenerated()) {
00394 return (*a)->senderBCI() - (*b)->senderBCI();
00395 } else {
00396 return (*a)->hasBeenGenerated() ? -1 : 1;
00397 }
00398 }
00399
00400
00401 void InlinedScope::epilogue() {
00402
00403 assert(exprStack()->isEmpty(), "expr. stack should be empty now");
00404
00405
00406 _subScopes->sort(compare_scopeBCIs);
00407
00408
00409 while (! _subScopes->isEmpty() && !_subScopes->last()->hasBeenGenerated()) _subScopes->pop();
00410 #ifdef ASSERT
00411 for (int i = 0; i < _subScopes->length(); i++) {
00412 if (!_subScopes->at(i)->hasBeenGenerated()) fatal("unused scopes should be at end");
00413 }
00414 #endif
00415
00416 if (_nofSends > 0 && containsNLR()) {
00417
00418
00419
00420
00421 addResult(new UnknownExpr(resultPR, NULL));
00422
00423 (void)nlrTestPoint();
00424 assert(has_nlrTestPoint(), "should have a NLR test point now");
00425 }
00426
00427
00428 if (has_nlrTestPoint()) {
00429
00430
00431
00432 } else if (isTop() && theCompiler->nlrTestPoints->nonEmpty()) {
00433
00434
00435 (void)nlrTestPoint();
00436 }
00437 if (!result) result = new NoResultExpr;
00438 theCompiler->exitScope(this);
00439 }
00440
00441
00442 bool InlinedScope::isSenderOf(InlinedScope* callee) const {
00443 assert(callee, "should have a scope");
00444 if (depth > callee->depth) return false;
00445 int d = callee->depth - 1;
00446 for (InlinedScope* s = callee->sender(); s && d >= depth; s = s->sender(), d--) {
00447 if (this == s) return true;
00448 }
00449 return false;
00450 }
00451
00452
00453 void InlinedScope::addSend(GrowableArray<PReg*>* expStk, bool isSend) {
00454
00455 if (!expStk) return;
00456 for (InlinedScope* s = this; s && s->isInlinedScope(); s = s->sender()) {
00457 if (isSend) s->_nofSends++;
00458 s->_nofInterruptPoints++;
00459 s->markLocalsDebugVisible(expStk);
00460 }
00461 }
00462
00463
00464 void InlinedScope::markLocalsDebugVisible(GrowableArray<PReg*>* exprStack) {
00465
00466 int i;
00467 if (_nofSends <= 1) {
00468
00469 self()->preg()->debug = true;
00470 for (i = nofArguments() - 1; i >= 0; i--) {
00471 argument(i)->preg()->debug = true;
00472 }
00473 for (i = nofTemporaries() - 1; i >= 0; i--) {
00474 temporary(i)->preg()->debug = true;
00475 }
00476
00477 GrowableArray<Expr*>* ct = contextTemporaries();
00478 if (ct != NULL) {
00479 for (i = 0; i < ct->length(); i++) {
00480 ct->at(i)->preg()->debug = true;
00481 }
00482 }
00483 }
00484
00485
00486
00487 for (i = 0; i < exprStack->length(); i++) {
00488 exprStack->at(i)->debug = true;
00489 }
00490 }
00491
00492
00493 void InlinedScope::setExprForBCI(int bci, Expr* expr) {
00494 assert(_exprStackElems->at_grow(bci) == NULL, "only one expr per BCI allowed");
00495 _exprStackElems->at_put_grow(bci, expr);
00496 }
00497
00498
00499 void InlinedScope::set2ndExprForBCI(int bci, Expr* expr) {
00500 _exprStackElems->at_put_grow(bci, expr);
00501 }
00502
00503
00504 void InlinedScope::set_self(Expr* e) {
00505 assert(!_self, "self already set");
00506 assert(e->scope()->isSenderOrSame(this), "must be in sender scope");
00507 _self = e;
00508 }
00509
00510
00511 int InlinedScope::homeContext() const {
00512
00513
00514 int context = -1;
00515 methodOop method = _method;
00516 while (method != NULL) {
00517 if (method->allocatesInterpretedContext()) { context++; }
00518 method = method->parent();
00519 }
00520 assert(context >= 0, "there must be at least one context");
00521 return context;
00522 }
00523
00524
00525 InlinedScope* InlinedScope::find_scope(int c, int& nofIndirections, OutlinedScope*& out) {
00526
00527
00528
00529
00530
00531
00532
00533 assert(c >= 0, "context must be >= 0");
00534 int distance = _method->lexicalDistance(c);
00535 nofIndirections = -1;
00536 Scope* s = this;
00537 out = NULL;
00538
00539 for (int d = distance; d > 0 && s->parent()->isInlinedScope(); d--, s = s->parent()) ;
00540 if (d == 0) {
00541
00542 return (InlinedScope*)s;
00543 }
00544
00545
00546
00547 InlinedScope* top = (InlinedScope*)s;
00548 if (top->allocatesCompiledContext()) nofIndirections++;
00549 Scope* prev = s;
00550 for (s = s->parent(); d > 0; d--, prev = s, s = s->parent()) {
00551 if (s->allocatesCompiledContext()) nofIndirections++;
00552 }
00553 assert(prev->isOutlinedScope(), "must be outlined scope");
00554 out = (OutlinedScope*)prev;
00555 assert(nofIndirections >= 0, "must have at least one context access");
00556 return top;
00557 }
00558
00559
00560 void InlinedScope::collectContextInfo(GrowableArray<InlinedScope*>* contextList) {
00561
00562 if (allocatesInterpretedContext()) contextList->append(this);
00563 for (int i = _subScopes->length() - 1; i >= 0; i--) {
00564 _subScopes->at(i)->collectContextInfo(contextList);
00565 }
00566 }
00567
00568
00569 int InlinedScope::number_of_noninlined_blocks() {
00570
00571 int nblocks = 0;
00572 for (int i = bbIterator->exposedBlks->length() - 1; i >= 0; i--) {
00573 BlockPReg* blk = bbIterator->exposedBlks->at(i);
00574 if (blk->isUsed() && isSenderOrSame(blk->scope())) nblocks++;
00575 }
00576 return nblocks;
00577 }
00578
00579
00580 void InlinedScope::generateDebugInfoForNonInlinedBlocks() {
00581 for (int i = bbIterator->exposedBlks->length() - 1; i >= 0; i--) {
00582 BlockPReg* blk = bbIterator->exposedBlks->at(i);
00583 if (blk->isUsed()) blk->closure()->generateDebugInfo();
00584 }
00585 }
00586
00587
00588 void InlinedScope::copy_noninlined_block_info(nmethod* nm) {
00589 for (int i = bbIterator->exposedBlks->length() - 1; i >= 0; i--) {
00590 BlockPReg* blk = bbIterator->exposedBlks->at(i);
00591 if (blk->isUsed()) {
00592 int offset = theCompiler->scopeDescRecorder()->
00593 offset_for_noninlined_scope_node(blk->closure()->noninlined_block_scope());
00594 nm->noninlined_block_at_put(blk->closure()->id().minor(), offset);
00595 }
00596 }
00597 }
00598
00599
00600
00601
00602 void InlinedScope::addTypeTest(NonTrivialNode* t) {
00603 assert(t->doesTypeTests(), "shouldn't add");
00604 _typeTests->append(t);
00605 }
00606
00607 CompiledLoop* InlinedScope::addLoop() {
00608 CompiledLoop* l = new CompiledLoop;
00609 _loops->append(l);
00610 return l;
00611 }
00612
00613 void InlinedScope::optimizeLoops() {
00614 for (int i = _loops->length() - 1; i >= 0; i--) {
00615 CompiledLoop* loop = _loops->at(i);
00616 char* msg = loop->recognize();
00617 if (msg) {
00618 cout(PrintLoopOpts)->print("*loop %d in scope %s not an integer loop: %s\n", i, key()->print_string(), msg);
00619 } else {
00620 cout(PrintLoopOpts)->print("*optimizing integer loop %d in scope %s\n", i, key()->print_string());
00621 loop->optimizeIntegerLoop();
00622 }
00623 if (OptimizeLoops) loop->optimize();
00624 }
00625 for (i = _subScopes->length() - 1; i >= 0; i--) {
00626 _subScopes->at(i)->optimizeLoops();
00627 }
00628 }
00629
00630
00631
00632
00633
00634 void InlinedScope::addToPRegsBegSorted(PReg* r) {
00635 assert(PrologueBCI <= r->begBCI() && r->begBCI() <= EpilogueBCI, "illegal bci");
00636 assert(_pregsBegSorted->isEmpty() || _pregsBegSorted->last()->begBCI() <= r->begBCI(), "sort order wrong");
00637 _pregsBegSorted->append(r);
00638 }
00639
00640
00641 void InlinedScope::addToPRegsEndSorted(PReg* r) {
00642 assert(PrologueBCI <= r->endBCI() && r->endBCI() <= EpilogueBCI, "illegal bci");
00643 assert(_pregsEndSorted->isEmpty() || _pregsEndSorted->last()->endBCI() <= r->endBCI(), "sort order wrong");
00644 _pregsEndSorted->append(r);
00645 }
00646
00647
00648 void InlinedScope::allocatePRegs(IntFreeList* f) {
00649 int bci = PrologueBCI;
00650 int bi = 0;
00651 int si = 0;
00652 int ei = 0;
00653 int blen = _pregsBegSorted->length();
00654 int slen = _subScopes->length();
00655 int elen = _pregsEndSorted->length();
00656 int n = f->allocated();
00657 assert(blen == elen, "should be the same");
00658 while (bci <= EpilogueBCI) {
00659
00660 while (bi < blen && _pregsBegSorted->at(bi)->begBCI() == bci) {
00661 _pregsBegSorted->at(bi)->allocateTo(Mapping::localTemporary(f->allocate()));
00662 bi++;
00663 assert(bi == blen ||
00664 _pregsBegSorted->at(bi)->begBCI() >= _pregsBegSorted->at(bi-1)->begBCI(),
00665 "_pregsBegSorted not sorted");
00666 }
00667
00668 while (si < slen && _subScopes->at(si)->senderBCI() == bci) {
00669 _subScopes->at(si)->allocatePRegs(f);
00670 si++;
00671 assert(si == slen ||
00672 _subScopes->at(si)->senderBCI() >= _subScopes->at(si-1)->senderBCI(),
00673 "_subScopes not sorted");
00674 }
00675
00676 while (ei < elen && _pregsEndSorted->at(ei)->endBCI() == bci) {
00677 f->release(Mapping::localTemporaryIndex(_pregsEndSorted->at(ei)->loc));
00678 ei++;
00679 assert(ei == elen ||
00680 _pregsEndSorted->at(ei)->endBCI() >= _pregsEndSorted->at(ei-1)->endBCI(),
00681 "_pregsEndSorted not sorted");
00682 }
00683
00684 bci = min(bi < blen ? _pregsBegSorted->at(bi)->begBCI() : EpilogueBCI + 1,
00685 si < slen ? _subScopes->at(si)->senderBCI() : EpilogueBCI + 1,
00686 ei < elen ? _pregsEndSorted->at(ei)->endBCI() : EpilogueBCI + 1);
00687 }
00688 assert(f->allocated() == n, "inconsistent allocation/release");
00689 }
00690
00691
00692 int InlinedScope::allocateFloatTemporaries(int firstFloatIndex) {
00693 assert(firstFloatIndex >= 0, "illegal firstFloatIndex");
00694 _firstFloatIndex = firstFloatIndex;
00695 int nofFloatTemps = hasFloatTemporaries() ? nofFloatTemporaries() : 0;
00696
00697 for (int k = 0; k < nofFloatTemps; k++) {
00698 PReg* preg = floatTemporary(k)->preg();
00699 Location loc = preg->loc;
00700 assert(loc.scopeNo() == scopeID() && loc.floatNo() == k, "inconsistency");
00701 preg->loc = Mapping::floatTemporary(scopeID(), k);
00702 assert(preg->loc.isStackLocation(), "must be a stack location");
00703 }
00704 int startFloatIndex = firstFloatIndex + nofFloatTemps;
00705 int totalNofFloatsInSubscopes = 0;
00706
00707 int len = _subScopes->length();
00708 for (int i = 0; i < len; i++) {
00709 InlinedScope* scope = _subScopes->at(i);
00710 totalNofFloatsInSubscopes = max(totalNofFloatsInSubscopes, scope->allocateFloatTemporaries(startFloatIndex));
00711 }
00712 return nofFloatTemps + totalNofFloatsInSubscopes;
00713 }
00714
00715
00716 bool MethodScope::isRecursiveCall(methodOop method, klassOop rcvrKlass, int depth) {
00717
00718 if (method == _method && rcvrKlass == selfKlass()) {
00719 if (depth <= 1) {
00720 return true;
00721 } else {
00722
00723 depth--;
00724 }
00725 }
00726
00727 if (isTop()) {
00728 return false;
00729 } else {
00730 return sender()->isRecursiveCall(method, rcvrKlass, depth);
00731 }
00732 }
00733
00734
00735 bool BlockScope::isRecursiveCall(methodOop method, klassOop rcvrKlass, int depth) {
00736 if (method == _method) {
00737 if (depth <= 1) {
00738 return true;
00739 } else {
00740
00741
00742
00743 return sender()->isRecursiveCall(method, rcvrKlass, --depth);
00744 }
00745 }
00746
00747
00748
00749 if (parent()->isOutlinedScope()) {
00750 return false;
00751 } else {
00752 return parent()->isRecursiveCall(method, rcvrKlass, depth);
00753 }
00754 }
00755
00756
00757 void InlinedScope::genCode() {
00758 _hasBeenGenerated = true;
00759 prologue();
00760
00761 _returnPoint = NodeFactory::new_MergeNode(EpilogueBCI);
00762 _NLReturnPoint = NodeFactory::new_MergeNode(EpilogueBCI);
00763 _nlrTestPoint = NULL;
00764 _contextInitializer = NULL;
00765 int nofTemps = method()->number_of_stack_temporaries();
00766 if (isTop()) {
00767 _returnPoint->append(NodeFactory::new_ReturnNode(resultPR, EpilogueBCI));
00768 _NLReturnPoint->append(NodeFactory::new_NLRSetupNode(resultPR, EpilogueBCI));
00769 Node* first = NodeFactory::new_PrologueNode(key(), nofArguments(), nofTemps);
00770 theCompiler->firstNode = first;
00771 gen()->setCurrent(first);
00772 }
00773
00774 assert(!hasTemporaries(), "should have no temporaries yet\n");
00775 createTemporaries(nofTemps);
00776
00777 int nofFloats = method()->total_number_of_floats();
00778 if (UseFPUStack) {
00779 const int FPUStackSize = 8;
00780 if (method()->float_expression_stack_size() <= FPUStackSize) {
00781
00782
00783 nofFloats = method()->number_of_float_temporaries();
00784 } else {
00785 warning("possible performance bug: cannot use FPU stack for float expressions");
00786 }
00787 }
00788 createFloatTemporaries(nofFloats);
00789
00790 assert(gen()->current() != NULL, "current() should have been set before");
00791 MethodIterator iter(method(), gen());
00792 if (gen()->aborting()) {
00793
00794 while (!exprStack()->isEmpty()) exprStack()->pop();
00795 }
00796 epilogue();
00797 }
00798
00799
00800
00801
00802 void InlinedScope::generateDebugInfo() {
00803
00804
00805 if (PrintDebugInfoGeneration) {
00806 if (isMethodScope()) {
00807 std->print_cr("self: %s", _self->preg()->name());
00808 } else {
00809 std->print_cr("no receiver (block method)");
00810 }
00811 }
00812
00813 ScopeDescRecorder* rec = theCompiler->scopeDescRecorder();
00814 int len, i;
00815
00816 if (!isLite()) {
00817
00818 if (hasTemporaries()) {
00819 len = _temporaries->length();
00820 for (i = 0; i < len; i++) {
00821 PReg* preg = _temporaries->at(i)->preg();
00822 rec->addTemporary(_scopeInfo, i, preg->createLogicalAddress());
00823 if (PrintDebugInfoGeneration) std->print_cr("temp[%2d]: %s", i, preg->name());
00824 }
00825 }
00826
00827 if (hasFloatTemporaries()) {
00828 len = _floatTemporaries->length();
00829 for (i = 0; i < len; i++) {
00830 PReg* preg = _floatTemporaries->at(i)->preg();
00831 rec->addTemporary(_scopeInfo, i, preg->createLogicalAddress());
00832 if (PrintDebugInfoGeneration) std->print_cr("float[%2d]: %s", i, preg->name());
00833 }
00834 }
00835
00836 if (allocatesInterpretedContext()) {
00837 len = _contextTemporaries->length();
00838 for (i = 0; i < len; i++) {
00839 PReg* preg = _contextTemporaries->at(i)->preg();
00840 rec->addContextTemporary(_scopeInfo, i, preg->createLogicalAddress());
00841 if (PrintDebugInfoGeneration) std->print_cr("c_temp[%2d]: %s", i, preg->name());
00842 }
00843 }
00844
00845 len = _exprStackElems->length();
00846 for (i = 0; i < len; i++) {
00847 Expr* elem = _exprStackElems->at(i);
00848 if (elem != NULL) {
00849 PReg* r = elem->preg()->cpReg();
00850 if (r->scope()->isSenderOrSame(this)) {
00851
00852
00853
00854
00855 rec->addExprStack(_scopeInfo, i, r->createLogicalAddress());
00856 if (PrintDebugInfoGeneration) std->print_cr("expr[%2d]: %s", i, r->name());
00857 } else {
00858
00859
00860
00861
00862 }
00863 }
00864 }
00865 }
00866
00867
00868 len = _subScopes->length();
00869 for (i = 0; i < len; i++) {
00870 InlinedScope* s = _subScopes->at(i);
00871 if (PrintDebugInfoGeneration) std->print_cr("Subscope %d (id = %d):", i, s->scopeID());
00872 s->generateDebugInfo();
00873 }
00874 }
00875
00876
00877 void MethodScope::generateDebugInfo() {
00878 ScopeDescRecorder* rec = theCompiler->scopeDescRecorder();
00879 const bool visible = true;
00880 _scopeInfo =
00881 rec->addMethodScope(
00882 _key,
00883 _method,
00884 _self->preg()->createLogicalAddress(),
00885 allocatesCompiledContext(),
00886 isLite(),
00887 _scopeID,
00888 _sender ? _sender->scopeInfo() : NULL,
00889 _senderBCI,
00890 visible
00891 );
00892 InlinedScope::generateDebugInfo();
00893 }
00894
00895
00896 void BlockScope::generateDebugInfo() {
00897 ScopeDescRecorder* rec = theCompiler->scopeDescRecorder();
00898 if (_parent->isOutlinedScope()) {
00899 _scopeInfo =
00900 rec->addTopLevelBlockScope(
00901 _method,
00902 _self->preg()->createLogicalAddress(),
00903 _self->klass(),
00904 allocatesCompiledContext()
00905 );
00906 } else {
00907 assert(_parent->isInlinedScope(), "oops");
00908 const bool visible = true;
00909 _scopeInfo =
00910 rec->addBlockScope(
00911 _method,
00912 ((InlinedScope*)_parent)->scopeInfo(),
00913 allocatesCompiledContext(),
00914 isLite(),
00915 _scopeID,
00916 _sender->scopeInfo(),
00917 _senderBCI,
00918 visible
00919 );
00920 }
00921 InlinedScope::generateDebugInfo();
00922 }
00923
00924
00925
00926
00927 OutlinedScope* new_OutlinedScope(nmethod* nm, ScopeDesc* sc) {
00928 if (sc->isMethodScope()) {
00929 return new OutlinedMethodScope(nm, sc);
00930 } else {
00931 return new OutlinedBlockScope(nm, sc);
00932 }
00933 }
00934
00935
00936 OutlinedScope::OutlinedScope(nmethod* nm, ScopeDesc* scope) {
00937 _nm = nm;
00938 _scope = scope;
00939 }
00940
00941
00942 OutlinedBlockScope::OutlinedBlockScope(nmethod* nm, ScopeDesc* sc) : OutlinedScope(nm, sc) {
00943 ScopeDesc* parent = sc->parent(true);
00944 if (parent) {
00945 _parent = new_OutlinedScope(nm, parent);
00946 } else {
00947 _parent = NULL;
00948 }
00949 }
00950
00951
00952 Expr* OutlinedScope::receiverExpr(PReg* p) const { return _scope->selfExpr(p); }
00953 methodOop OutlinedScope::method() const { return _scope->method(); }
00954 klassOop OutlinedMethodScope::methodHolder() const {
00955 return selfKlass()->klass_part()->lookup_method_holder_for(method());
00956 }
00957
00958
00959
00960
00961 void SendInfo::print() {
00962 lprintf("SendInfo %#lx \"", this);
00963 sel->print_symbol_on();
00964 lprintf("\" (rcvr = %#lx, nsends = %ld)\n", rcvr, nsends);
00965 }
00966
00967
00968 void InlinedScope::printTree() {
00969 print();
00970 for (int i = 0; i < _subScopes->length(); i++) {
00971 _subScopes->at(i)->printTree();
00972 }
00973 }
00974
00975 void InlinedScope::print() {
00976 lprintf(" method: %#lx\n\tid: %ld", method(), scopeID());
00977 lprintf("\nself: ");
00978 self()->print();
00979 for (int i = 0; i < nofArguments(); i++) {
00980 lprintf("arg %2d: ", i);
00981 argument(i)->print();
00982 }
00983 lprintf("\n");
00984 }
00985
00986
00987 void MethodScope::print_short() {
00988 lprintf("(MethodScope*)%#lx (", this); selector()->print_symbol_on(); lprintf(")");
00989 }
00990
00991
00992 void MethodScope::print() {
00993 print_short();
00994 InlinedScope::print();
00995 if (sender()) { lprintf(" sender: "); sender()->print_short(); }
00996 lprintf(" @ %ld\n", senderBCI());
00997 method()->pretty_print();
00998 }
00999
01000
01001 void BlockScope::print() {
01002 print_short();
01003 InlinedScope::print();
01004 if (parent()) { printf("\tparent: "); parent()->print_short(); }
01005 if (sender()) { lprintf(" sender: "); sender()->print_short(); }
01006 lprintf(" @ %ld\n", senderBCI());
01007 method()->pretty_print();
01008 }
01009
01010
01011 void BlockScope::print_short() {
01012 lprintf("(BlockScope*)%#lx (", this); selector()->print_symbol_on();
01013 lprintf(" %#lx)", method());
01014 }
01015
01016
01017 void OutlinedScope::print_short(char* name) {
01018 lprintf("(%s*)%#lx (", name, this);
01019 _scope->selector()->print_symbol_on();
01020 lprintf(")");
01021 }
01022
01023
01024 void OutlinedScope::print(char* name) {
01025 print_short(name);
01026 lprintf(" _nm = %#lx, _scope = %#lx", _nm, _scope);
01027 }
01028
01029
01030 void OutlinedMethodScope::print_short() { OutlinedScope::print_short("OutlinedMethodScope"); }
01031 void OutlinedMethodScope::print() { OutlinedScope::print("OutlinedMethodScope"); }
01032
01033 void OutlinedBlockScope::print() {
01034 OutlinedScope::print("OutlinedMethodScope");
01035 if (parent()) { lprintf("\n parent: "); parent()->print_short(); }
01036 lprintf("\n");
01037 }
01038
01039 void OutlinedBlockScope::print_short() { OutlinedScope::print_short("OutlinedMethodScope"); }
01040
01041 # endif