char* sendDesc::fastCacheLookupAndBackpatch( LookupType t, mapOop receiverMapOop, oop sel, oop del ) { if (needsDelegatee(t) || isResendLookupType(t) || isPerformLookupType(t)) { // too complicated to short-circuit these lookups return NULL; } // try mh-independent MethodLookupKey key(t, MH_TBD, receiverMapOop, sel, del); nmethod* nm= Memory->code->lookup(key); if (nm == NULL) { NumberOfFastLookupMisses++; return NULL; } NumberOfFastLookupHits++; if (nm->needToRecompileFor(this)) return NULL; if (InlineCache) { NumberOfICMisses++; extend(nm, receiverMapOop, NULL); } return nm->verifiedEntryPoint(); }
bool sendDesc::checkLookupTypeAndEntryPoint(nmethod *nm, char *entryPoint) { LookupType lsrc= lookupType() & ~ImplicitSelfBit; LookupType ldst= nm->key.lookupType & ~ImplicitSelfBit; bool rcvrStaticLookupType= lsrc & ReceiverStaticBit; // dstStaticLookupType==true implies no map check in prologue of nm bool dstStaticLookupType= ldst & ReceiverStaticBit; lsrc &= ~ReceiverStaticBit; ldst &= ~ReceiverStaticBit; bool callsPrologue= entryPoint == nm->insts() && !dstStaticLookupType; bool skipsPrologue= entryPoint == nm->verifiedEntryPoint(); // if things are really broken, neither callsPrologue nor // skipsPrologue is true if (pic()) return skipsPrologue && (ReuseNICMethods && nm->reusable() ? lookupMatch(lsrc, ldst) : lsrc == ldst); if (!ReuseNICMethods) return lsrc == ldst && (rcvrStaticLookupType ? skipsPrologue : callsPrologue); if (!rcvrStaticLookupType) return lookupMatch(lsrc, ldst) && callsPrologue; // check entry point if ( (lookupType() & ImplicitSelfBit) && !isResendLookupType(lsrc) && nmethod::findNMethod(this)->reusable()) { // If we don't really know the receiver type for sure // (because the it's an implicit self send and the // sending method is reusable), // we must use the non-verified entry point. Resends are OK -- // we'll still be invoking the right method. if (!callsPrologue) return false; } else { if (!skipsPrologue) return false; } // Check lookup types. If target is reusable, // lookup types need not match precisely, only enough to ensure // prologues and return addresses match return nm->reusable() ? lookupMatch(lsrc, ldst) : lsrc == ldst; }
vframeLookup::vframeLookup( LookupType l, oop rcvr, oop sel, oop dgt, oop smhOrMap, abstract_vframe* f, dependencyList* dps, assignableDependencyList *adps ) : simpleLookup( l, rcvr, sel, dgt, smhOrMap, dps, adps ) { sendingVFrame= f; if (f == NULL) return; if (!isResendLookupType(lookupType())) { key.set_methodHolder_or_map( MH_NOT_A_RESEND); return; } oop vfmh= sendingVFrame->methodHolder_or_map(); if (!vfmh->is_map()) { key.set_methodHolder_or_map( vfmh); return; } // method holder is the same as self; replace it now if (smhOrMap == MH_TBD) { // don't have run-time smh, so compute it (e.g. for conversions) key.set_methodHolder_or_map( sendingVFrame->methodHolder_object() ); return; } // just use smh # if GENERATE_DEBUGGING_AIDS if (CheckAssertions) { oop smh2 = sendingVFrame->methodHolder_object(); assert(smhOrMap == smh2, "runtime sending method holder should be correct"); /* this is not always true with programming mapOop map2 = smh2->map()->enclosing_mapOop(); assert(vfmh == map2, "should be the same map"); */ } # endif }