int32 MethodLookupKey::hash() { int32 i; // Coded for speed - called for every codeTable lookup // XOR the identity-hash values of the fields. For efficiency, just // xor the marks and extract hash bits at the end instead of doing // this for every field. // Also, don't need to check for no_hash: real keys are guaranteed // to have an id hash value because init_hash is called before a // key is added to the table. If a lookup key contains oops with // no_hash, we'll have a bogus hash value, but we won't find anything // anyway. i = (int32)receiverMapOop()->mark(); if (selector->is_mem()) i ^= (int32)memOop(selector)->mark(); // Can't do the optimization for the methodHolder - it might be // e.g. a smiOop in the lookupError glue method. // Not non-zero often enough to hash on // (an optimization for speed; Bay's idea) // i ^= (int32)delegatee ->mark(); return (lookupType & ~ImplicitSelfBit) ^ markOop(i)->hash() ^ methodHolder_or_map()->identity_hash(); }
bool SMethodScope::isRecursiveCall(oop meth, oop rcvrMap, fint n) { if (meth == method()) { if (receiverMapOop() == rcvrMap) { if (n <= 1) return true; else n--; } } SScope* s = sender(); return s && s->isRecursiveCall(meth, rcvrMap, n); }
bool NMethodLookupKey::verify() { bool flag = true; if (!oop(receiverMapOop())->verify_oop()) { lprintf("\tin receiverMap of NMethodLookupKey 0x%lx\n", this); flag = false; } else if (!receiverMapOop()->is_map()) { error1("receiverMapOop() 0x%lx isn't a map", receiverMapOop()); flag = false; } if ( methodHolder_or_map() != MH_TBD && !methodHolder_or_map()->verify_oop()) { lprintf("\tin methodHolder of NMethodLookupKey 0x%lx\n", this); flag = false; } if (selector) { if (!selector->verify_oop()) { lprintf("\tin selector of NMethodLookupKey 0x%lx\n", this); flag = false; /* uncommon but legal } else if (!selector->is_string()) { lprintf("warning: selector "); selector->print_oop(); lprintf(" isn't a string\n"); flag = false; */ } } if (delegatee) { if (!delegatee->verify_oop()) { lprintf("\tin delegatee of NMethodLookupKey 0x%lx\n", this); flag = false; } else { BaseLookupType l = baseLookupType(lookupType); if (l == DirectedResendBaseLookupType && ! delegatee->is_string()) { error1("delegatee 0x%lx isn't a string", delegatee); flag = false; } } } return flag; }
bool SVFrameMethodScope::isRecursiveCall(oop meth, oop rcvrMap, fint n) { // potential performance bug (bad interaction with block cloning) // fix this if (meth == method()) { if (receiverMapOop() == rcvrMap) { return true; } } SScope* s = sender(); return s && s->isRecursiveCall(meth, rcvrMap, n); }
lookupTarget* baseCompileTimeLookup::undirected_resend_lookup_target() { if (!methodHolder_or_map()->is_map()) { return simpleLookup::undirected_resend_lookup_target(); } else { // don't know actual value of lookup start location assert(methodHolder_or_map() == receiverMapOop(), "expecting receiver and sending method holder to be in same map"); return (new mapLookupTarget(methodHolder_map())) -> be_receiver(); } }
void MethodLookupKey::print() { printIndent(); lprintf("MethodLookupKey: rcvMap = 0x%lx, mh = ", (long unsigned)receiverMapOop()); if (methodHolder_or_map() == MH_TBD) { lprintf("<to be determined>"); } else { methodHolder_or_map()->print_real_oop(); } lprintf(",\n"); printIndent(); lprintf(" sel = "); selector->print_real_oop(); lprintf(", del = "); delegatee->print_real_oop(); lprintf(",\n"); printIndent(); lprintf(" type = "); printLookupType(lookupType); lprintf("\n"); }
void MethodLookupKey::init_hash() { receiverMapOop() ->identity_hash(); methodHolder_or_map()->identity_hash(); selector ->identity_hash(); delegatee ->identity_hash(); }