// an optimized version inline oop blockOopClass::really_clone_block(smiOop fp) { assert_block(this, "not a block"); assert_smi(fp, "not a smallInt or pointer"); NumberOfBlockClones++; const int32 size = sizeof(blockOopClass)/oopSize; // would be cleaner (but slightly slower in the fast case) to do // b= Memory->alloc_objs(size); // if (Memory->new_gen->eden_space->contains(b)) ... blockOopClass* b= (blockOopClass*) Memory->new_gen->eden_space->alloc_objs_local(size); if (b) { # if GENERATE_DEBUGGING_AIDS if (CheckAssertions && b == (blockOopClass*)catchThisOne) { warning1("blockOopClass::really_clone_block caught 0x%lx", b); } # endif // allocated in eden; don't do check stores or scavenging b->_map = addr()->_map; b->setHomeFr(fp); blockOop b1 = as_blockOop(b); b1->init_mark(); return b1; } else { // overflowed eden; do check stores when done b = (blockOopClass*) Memory->alloc_objs(size); Memory->store((oop*) &b->_map, addr()->_map); b->setHomeFr(fp); blockOop b1 = as_blockOop(b); b1->init_mark(); return b1; } }
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::tryLookupOfBlockMethod( SendInfo* info, SExpr* rcvr, RScope* rs, oop methodObj, SICLookup* L) { // inline block method (value, value: etc) if (!shouldInlineBlock(info, rs, rcvr, methodObj)) return notify(info->sel, "rejected"); SScope* parentScope; if (rcvr->isClonedBlockSExpr()) { // result of a BlockClone node parentScope = ((ClonedBlockSExpr*)rcvr)->blockScope(); assert(!parentScope->isVFrameScope(), "shouldn't be a vf scope"); assert(parentScope->isCodeScope(), "shouldn't be access"); } else if ( L->result()->as_real()->holder->is_map() && L->result()->as_real()->holder->map() == theSIC->L->receiverMap()) { // block is in same clone family as receiver block; therefore, // must have same parent scope as receiver block // example: value:With: sends value: assert_block(theSIC->L->receiver, "expecting a block literal"); blockOop block = (blockOop) theSIC->L->receiver; compiled_vframe* vf = block->parentVFrame(NULL)->as_compiled(); parentScope = new_SVFrameScope(vf); } else { // can't find nmethod for this block assert(! (L->result()->as_real()->holder->is_map() && L->result()->as_real()->holder->map()->equal( theSIC->L->receiverMap())), "block map cloning got us again"); return notify(info->sel, "unknown block"); } // fix rs here return new SBlockScope(methodObj, parentScope, this, rs, info); }
static oop_t home_frame(oop_t rcvr) { return BlockObj::from(assert_block(rcvr))->homeFramePointer(); }