/* Sun-$Revision: 23.7 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface // LookupKeys are various combinations of information that // describe lookups for scopes & nmethods. // The simplest, ScopeLookupKey, contains just enough info about a // lookup (or send) to meet the needs of a scope, where // the receiver is available separately. extern char* selector_string(oop sel); // NB: not a VMObj to save space (keys are stored in ScopeDescs) // scopes do not need receiver info here class ScopeLookupKey { public: LookupType lookupType; oop selector; // normally a string, BUT watch out for // _Perform: 17 !! oop delegatee; // zero if none ScopeLookupKey(LookupType l, oop s, oop d) { lookupType = l; selector = s; delegatee = d; } ScopeLookupKey() {} void set_from(ScopeLookupKey &nmk); bool equivalent(ScopeLookupKey &k) { return baseLookupType(lookupType) == baseLookupType(k.lookupType) && selector == k.selector && delegatee == k.delegatee; } void print(); }; // MethodLookupKeys add the receiver map to that info, // and are specific to a given receiver map. // MethodLookupKeys are only used during lookups. // When the lookup is done, the key should be discarded, as it // does not know how to participate in scavenging, GC, etc. // It should be a ResourceObj, except that NMethodLookupKey can't // be. class MethodLookupKey: public ScopeLookupKey { public: mapOop _receiverMapOop; protected: // method holder of sending method; // map if mh obj will always be same obj as rcvr // suppose an object includes a method that does a resend, // by keying nmethod found for the resend on a MAP, // the nmethod can be reused for clones of the object // NULL if lookup not a resend; // badOop if not yet determined # define MH_NOT_A_RESEND NULL # define MH_TBD badOop oop _methodHolder_or_map; public: MethodLookupKey(LookupType l, oop mh, mapOop rm, oop s, oop d) : ScopeLookupKey(l, s, d) { _receiverMapOop = rm; _methodHolder_or_map= isResendLookupType(lookupType) ? mh : oop(MH_NOT_A_RESEND); } mapOop receiverMapOop() { return _receiverMapOop; } Map* receiverMap() { return receiverMapOop()->addr(); } void set_methodHolder_or_map(oop mh) { _methodHolder_or_map= mh; } oop methodHolder_or_map() { return _methodHolder_or_map; } MethodLookupKey(MethodLookupKey* k) { *this = *k; } MethodLookupKey() : ScopeLookupKey(0, badOop, badOop) { _receiverMapOop= mapOop(badOop); _methodHolder_or_map= MH_TBD; } void set_from(MethodLookupKey &nmk); bool EQ(const MethodLookupKey& p) { return (lookupType & ~ImplicitSelfBit) == (p.lookupType & ~ImplicitSelfBit) && _receiverMapOop == p._receiverMapOop && _methodHolder_or_map == p._methodHolder_or_map && selector == p.selector && delegatee == p.delegatee; } int32 hash(); void init_hash(); fint arg_count() { return selector && selector->is_string() ? stringOop(selector)->arg_count() : 0; } char* selector_string() { return ::selector_string(selector); } void print(); }; inline MethodLookupKey *new_MethodLookupKey(MethodLookupKey &k) { MethodLookupKey* k2= NEW_RESOURCE_OBJ(MethodLookupKey); k2->set_from(k); return k2; } // An NMethodLookupKeys is a MethodLookupKey stored in an nmethod or // in the code table. class NMethodLookupKey: public MethodLookupKey { public: NMethodLookupKey(NMethodLookupKey* k) { *this = *k; } NMethodLookupKey() {} bool is_new() { return receiverMapOop() ->is_new() || methodHolder_or_map() ->is_new() || selector ->is_new() || delegatee ->is_new(); } void scavenge_contents(); void gc_mark_contents(); void gc_unmark_contents(); void switch_pointers(oop from, oop to); void relocate(); bool verify(); void oops_do(oopsDoFn f); };