void SICompiler::initTopScope() { recompileeScope = recompilee ? (RScope*)constructRScopes(recompilee) : (RScope*)new RNullScope(NULL); if (PrintPICScopes) recompileeScope->printTree(0, 0); nodeGen->haveStackFrame = true; MethodKind kind = method()->kind(); countID = Memory->code->nextNMethodID(); SCodeScope* s; SScope* parentScope = NULL; if (L->receiverMap()->is_block()) { blockOop block = (blockOop) L->receiver; assert_block(block, "expecting a block literal"); // caution: parentFrame could be on conversion stack, so use // sending frame as a starting point // I think this hint is bogus--dmu (see NIC) frame* sender = L->sendingVFrame ? L->sendingVFrame->fr : currentProcess->last_self_frame(false); parentVFrame = block->parentVFrame(sender, true)->as_compiled(); if (parentVFrame) parentScope = new_SVFrameScope(parentVFrame); } MethodLookupKey* k= new_MethodLookupKey(L->key); SendInfo* info = new SendInfo(k); switch (kind) { case OuterMethodType: s = new SMethodScope(method(), methodHolder_or_map(), NULL, recompileeScope, info); break; case BlockMethodType: // taken from NIC by dmu 7/1 assert(L->receiverMap()->is_block(), "was expecting block"); if (parentScope) { s = new SBlockScope(method(), parentScope, NULL, recompileeScope, info); } else { s = new SDeadBlockScope(method(), info); } break; default: fatal("unexpected byte code kind"); } needRegWindowFlushes = false; topScope = s; s->vscope = vscopes ? vscopes->top() : NULL; }
SSelfScope* SCodeScope::tryLookup(SendInfo* info, SExpr* rcvr) { // info->rcvr is the overall receiver (e.g. a merge expr), rcvr is // a particular branch // nmln* depsTop = theSIC->L->deps->top; assert(rcvr->hasMap(), "should have a map"); SICLookup* L = new SICLookup(info->l, rcvr->isConstantSExpr() ? rcvr->asConstantSExpr()->constant() : rcvr->map()->enclosing_mapOop(), info->sel, info->del, theSIC->L->deps, this ); L->perform_lookup(); info->key= new_MethodLookupKey(L->key); if (L->result() == NULL) { // nothing found statically // should remove unused deps here if (L->status == foundNone) { // next recompilation might get it via PICs theSIC->registerUninlinable(info, NormalFnLimit, 0); } else { info->uninlinable = true; } char msg[80]; sprintf(msg, "lookup failed: %s", lookupStatusString(L->status)); return notify(info->sel, msg); } slotDesc* s = L->result()->as_real()->desc; assert(! s->is_vm_slot(), "shouldn't be a vm slot"); RScope* rs = rscope->subScope(_bci, L); # if GENERATE_DEBUGGING_AIDS if (CheckAssertions) { bool isNullRScope = rs->isNullScope(); // for breakpoints } # endif if (s->is_map_slot()) { // handle constant slots first if ( !s->data->has_code()) { // inline value of a constant slot msgCost = 0; return new SConstantSlotAccessScope(L, this, rs, rcvr, info); } switch ( s->data->kind() ) { case BlockMethodType: return tryLookupOfBlockMethod(info, rcvr, rs, s->data, L); case OuterMethodType: return tryLookupOfOuterMethod(info, rcvr, rs, s->data, L); default: fatal("unexpected kind of code in slot"); } } assert(s->is_obj_slot(), "unexpected slot type"); // is not map slot // found a slot in the receiver or one of its ancestors msgCost = 0; return info->sel->is_1arg_keyword() ? // inline assignment to an instance variable (SSelfScope*) new SDataSlotAssignScope(L, this, rs, rcvr, exprStack->top(), info) : // inline access of an instance variable (SSelfScope*) new SDataSlotAccessScope(L, this, rs, rcvr, info); }