char* nmethod::entryPointFor(sendDesc *sd) { if (sd->pic()) return verifiedEntryPoint(); bool rcvrStaticLookupType= sd->lookupType() & ReceiverStaticBit; if (!rcvrStaticLookupType) return insts(); return ReuseNICMethods && findNMethod(sd)->reusable() ? insts() : verifiedEntryPoint(); }
nmethod* nmethod::nmethodContaining(char* pc, char* likelyEntryPoint) { assert(Memory->code->contains(pc), "should contain address"); if (likelyEntryPoint && Memory->code->contains(likelyEntryPoint)) { nmethod* result = nmethod_from_insts(likelyEntryPoint); if (result->contains(pc)) return result; } return findNMethod(pc); }
void FlatProfiler::record_tick_for_running_frame(frame fr) { // The tick happend in real code -> non VM code if (fr.is_interpreted_frame()) { methodOop method = fr.method(); if (method == NULL) return; assert(method->is_method(), "must be method"); FlatProfiler::interpreted_update(method, fr.receiver()->klass(), in_code); } else if (fr.is_compiled_frame()) { FlatProfiler::compiled_update(findNMethod(fr.pc()), in_code); } else if (PIC::in_heap(fr.pc())) { PIC* pic = PIC::find(fr.pc()); FlatProfiler::compiled_update(findNMethod((char*) pic->compiled_ic()), in_pic); } else if (StubRoutines::contains(fr.pc())) { FlatProfiler::stub_ticks++; } }
void frame::print() const { std->print("[%s frame: fp = %#lx, sp = %#lx, pc = %#lx", print_name(), fp(), sp(), pc()); if (is_compiled_frame()) { std->print(", nm = %#x", findNMethod(pc())); } else if (is_interpreted_frame()) { std->print(", hp = %#x, method = %#x", hp(), method()); } std->print_cr("]"); if (PrintLongFrames) { for (oop* p = sp(); p < (oop*)fp(); p++) std->print_cr(" - 0x%lx: 0x%lx", p, *p); } }
void nmethod::relinkDI(int32 n, nmln*& savedDIChildren) { Unused(n); int32 nlinks = 0; for (addrDesc* p = locs(), *pend = locsEnd(); p < pend; p++) { if (p->isDIDesc()) { assert(nlinks < n, "too many DI caches in method"); nmln* l = p->asDIDesc(this)->dependency(); assert(l->isEmpty(), "should be empty"); if (savedDIChildren[nlinks].notEmpty()) { nmln* ln = savedDIChildren[nlinks].next; // cfront bug! ln->rebind(l); nmethod* target = findNMethod(ln); p->asDIDesc(this)->set_jump_addr(target->insts()); assert(p->asDIDesc(this)->dependency()->notEmpty(), "should be rebound now"); } nlinks++; } } MachineCache::flush_instruction_cache_for_debugging(); assert(n == nlinks, "too few DI links in method"); }
void NLRSupport::non_lifo_abort(pc_t nonLifoAbortPC) { if (nonLifoAbortPC == 0) fatal("nonLifoAbortPC is zero"); // was in compiled code // need to flush nmethod of dead block (next invocation could be ok) nmethod* deadBlock = findNMethod(nonLifoAbortPC); // Initialize our return address so that it looks like our caller is C // (the "caller" really is the non-lifo block nmethod, but we can't display // its stack frame anyway, so we make it look like C). At the same time, // must make it look like our caller was invoked via // SendMessage_stub so that abort() // returns throudgh the inline cache. fix_current_return_address(Memory->code->trapdoors->SendMessage_stub_td()); Memory->code->chainFrames(); deadBlock->flush(); Memory->code->unchainFrames(); processSemaphore = false; // HACK to avoid assertion in Process:: transfer(), Lars currentProcess->nonLifoError(); }
void FlatProfiler::record_tick_for_calling_frame(frame fr) { // The tick happend in VM code TickPosition where = other; if (theCompiler) { where = in_compiler; } if (fr.is_interpreted_frame()) { methodOop method = fr.method(); if (method == NULL) return; assert(method->is_method(), "must be method"); int bci = method->bci_from(fr.hp()); if (Bytecodes::code_type((Bytecodes::Code) *method->codes(bci)) == Bytecodes::primitive_call) { where = in_primitive; } FlatProfiler::interpreted_update(method, fr.receiver()->klass(), where); } else if (fr.is_compiled_frame()) { nmethod* nm = findNMethod(fr.pc()); relocIterator iter(nm); while (iter.next()) { if (iter.is_call() && iter.call_end() == fr.pc()) { if (iter.type() == relocInfo::prim_type) where = in_primitive; } } FlatProfiler::compiled_update(nm, where); } else { if (StubRoutines::contains(fr.pc())) { FlatProfiler::stub_ticks++; } else { FlatProfiler::unknown_ticks++; } } }
bool nmethod::verify() { bool r = true; ResourceMark rm; r &= OopNCode::verify2("nmethod"); if (insts() != (char*)(this + 1)) { error1("nmethod at 0x%lx has incorrect insts pointer", this); r = false; } if (!Memory->code->contains(this)) { error1("nmethod at 0x%lx not in zone", this); r = false; } if (!zoneLink.verify_list_integrity()) { lprintf("\tof zoneLink of nmethod 0x%lx\n", this); r = false; } { FOR_MY_CODETABLE_ENTRIES(e) if (e->nm != this) { error1("bad code table link for nmethod %#lx\n", this); r = false; } } bool isAligned = (frame_size & (frame_word_alignment-1)) == 0; if (!isAligned) { lprintf("nmethod at %#lx: frame size is not multiple of %d words\n", (long unsigned)this, frame_word_alignment); r = false; } if (codeTableLink != NULL) { nmethod *tableResult = isDebug() ? Memory->code->debugTable->lookup(key) : Memory->code->table ->lookup(key); if (tableResult != this) { error1("nmethod at %#lx: code table lookup failed", this); r = false; } } if (!key.verify()) { lprintf("\tof key of nmethod 0x%lx\n", this); r = false; } { FOR_MY_CODETABLE_ENTRIES(e) if (!e->key.verify()) { lprintf("\tof code table key %#lx of nmethod 0x%lx\n", (long unsigned)&e->key, (long unsigned)this); r = false; } } if (!linkedSends.verify_list_integrity()) { lprintf("\tof linkedSends of nmethod 0x%lx\n", this); r = false; } if (!diLink.verify_list_integrity()) { lprintf("\tof diLink of nmethod 0x%lx\n", this); r = false; } r &= scopes->verify(); for (PcDesc* p = pcs(); p < pcsEnd(); p++) { if (! p->verify(this)) { lprintf("\t\tin nmethod at %#lx (pcs)\n", this); r = false; } } // more checks in ncode::verify called above bool shouldBeDI = diLink.notEmpty(); for (addrDesc* l = locs(); l < locsEnd(); l++) { if (l->isDIDesc()) { shouldBeDI = true; } } if (shouldBeDI && !isDI()) { error1("nmethod %#lx should be marked isDI", this); r = false; } else if (!shouldBeDI && isDI()) { error1("nmethod %#lx should not be marked isDI", this); r = false; } if (! key.receiverMap()->is_block() ) { for (nmln* d = deps(); d < depsEnd(); d++) { if (! d->verify_list_integrity()) { lprintf("\tin nmethod at %#lx (deps)\n", this); r = false; } } } if (frame_chain != NoFrameChain) { error1("nmethod %#lx has non-zero frame chain value", this); r = false; } if (findNMethod( instsEnd() - oopSize) != this) { error1("findNMethod did not find this nmethod (%#lx)", this); r = false; } return r; }
nmethod* frame::code() const { assert(is_compiled_frame(), "no code"); return findNMethod(pc()); }
void handleMapLoadTrap(InterruptedContext* c) { int32* pc = (int32*)c->pc(); assert(isMapLoad(pc), "not a map load"); assert(c->next_pc() == c->pc() + 4, "flow should be sequential"); Location dest = Location(rd(pc)); mapOop resultMap; // get the result map to load # if TARGET_OS_VERSION == SOLARIS_VERSION_broken // disabled for now -- there's some bug in get_reg --Urs 8/94 Location src = Location(rs1(pc)); fint rcvrTag = int(c->get_reg(src)) & Tag_Mask; if (rcvrTag == Int_Tag) { resultMap = Memory->smi_map->enclosing_mapOop(); } else if (rcvrTag == Float_Tag) { resultMap = Memory->float_map->enclosing_mapOop(); } else { fatal("bad receiver tag in map load trap"); } # else // Can't read registers, and signal handler doesn't get faulting address, // so don't know what the correct map is. But it's not really needed // (only important thing is that it's different from any mem map) since // the map testing code always checks the tag if an immediate is expected. resultMap = NULL; # endif NCodeBase* thing = findThing(pc); if (!thing->isNMethod()) { // a PIC -- no problem, will fix itself to eliminate trap } else { nmethod* nm = findNMethod(pc); if ((char*)pc >= nm->verifiedEntryPoint()) { // the trap happened in the body, not in the prologue if (nm->flags.trapCount > MapLoadTrapLimit) { // recompile the nmethod on next invocation to eliminate the traps nm->makeToBeRecompiled(); if (nm->isYoung()) // manipulate counters to provoke recompilation nm->makeVeryYoung(); else nm->makeYoung(); } else { nm->flags.trapCount++; if (nm->flags.trapCount <= 0) { // counter overflowed nm->flags.trapCount--; } } } } # if TARGET_OS_VERSION == SOLARIS_VERSION // simply set the destination register and continue c->set_reg(dest, resultMap); c->set_pc(c->next_pc()); c->set_next_pc(c->pc() + 4); # elif TARGET_OS_VERSION == SUNOS_VERSION // can't set register in interrupt handler - argh!! if (mapLoadHandler[dest]) { char* cont = c->next_pc(); InterruptedContext::set_continuation_address(first_inst_addr(mapLoadHandler[dest]), true, true); continuePC = cont; mapToLoad = resultMap; } else { fatal1("map load trap: bad destination register %d", dest); } # endif }