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