/* Sun-$Revision: 23.4 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface // A lookup target represents an object visited during a lookup. // By standing between the lookup routines and the real object, // these classes allow the lookup routines to handle vframes, // and to record paths (for DI, I think) class lookupTarget: public ResourceObj { protected: Map* targetMap; // used for lookup void set_map(Map* m) { targetMap = m;} public: Map* map() {return targetMap;} public: lookupTarget(Map* m) { set_map(m); } public: // EQ used by lookup to see if prev hit is same as this one virtual bool EQ(lookupTarget* t) = 0; // used by lookup // used for lookup virtual bool check_cycle_mark() { return false; } virtual void set_cycle_mark() {} virtual void clear_cycle_mark() {} virtual lookupTarget* get_target_for_slot(slotDesc* s, simpleLookup* L) = 0; virtual void add_slot_dependency(simpleLookup* L) { Unused(L); } virtual void add_dependency(slotDesc* s, simpleLookup* L) { Unused(s); Unused(L); } // for code gen, & to decide whether to cache method // for code gen virtual bool is_receiver() { return false;} virtual bool is_object() { return false; } virtual bool is_map() { return false; } virtual bool is_vframe() { return false; } virtual bool is_object_or_map() { return false; } // & for caching decision // for interpretation & al virtual oop get_slot(slotDesc* sd) { Unused(sd); ShouldNotCallThis(); return NULL; } virtual void set_slot(slotDesc* sd, oop x) { Unused(sd); Unused(x); ShouldNotCallThis(); } // used for equality predicates virtual bool is_scope() { return false; } virtual void print() = 0; protected: void printStatus(); }; class objectOrMapLookupTarget: public lookupTarget { protected: // records if this target is guaranteed to be the same // object or map as the receiver of the lookup bool _is_receiver; // easier to keep it in here public: objectOrMapLookupTarget(Map* m) : lookupTarget(m) { _is_receiver = false; } public: void add_slot_dependency(simpleLookup* L) { L->add_slot_dependency(map()); } void add_dependency(slotDesc* s, simpleLookup* L) { L->add_dependency(s, map()); } bool is_object_or_map() { return true; } lookupTarget* get_target_for_slot(slotDesc* s, simpleLookup* L) = 0; bool is_receiver() { return _is_receiver; } objectOrMapLookupTarget* be_receiver() { _is_receiver = true; return this; } }; struct assignableSlotLink: ResourceObj { slotDesc* slot; objectLookupTarget* target; assignableSlotLink* next; assignableSlotLink(slotDesc* s, objectLookupTarget* t) { slot = s; target = t; next = NULL; } assignableSlotLink* add(slotDesc* s, objectLookupTarget* t); void print(); }; class objectLookupTarget: public objectOrMapLookupTarget { public: oop obj; realSlotRef* prevTargetSlot; // used to generate code, set by lookup assignableSlotLink* links; // set by lookup, used to gen DI verify code // used to optimize DI check, records when exact identity of object // (as opposed to its map) is known statically // set upon compiler creation if lookup found a method (why?) -- dmu // also set mysteriously by EQ bool value_constrained; public: objectLookupTarget(oop p) : objectOrMapLookupTarget(p->map()) { obj = p; prevTargetSlot = NULL; links = NULL; value_constrained = false; } bool EQ(lookupTarget* t) { if (t->is_object()) { value_constrained = true; ((objectLookupTarget*) t)->value_constrained = true; return obj == ((objectLookupTarget*) t)->obj; } else { return false; } } bool check_cycle_mark() { return obj->is_mem() && memOop(obj)->is_marked(); } void set_cycle_mark() { if (obj->is_mem()) { assert(! memOop(obj)->is_marked(), "already marked!"); memOop(obj)->set_mark(); } } void clear_cycle_mark() { if (obj->is_mem()) { assert(memOop(obj)->is_marked(), "not already marked!"); memOop(obj)->clear_mark(); } } bool is_object() { return true; } lookupTarget* get_target_for_slot(slotDesc* s, simpleLookup* L); oop get_slot(slotDesc*); void set_slot(slotDesc*, oop); public: virtual void print_short(); void print(); }; class mapLookupTarget: public objectOrMapLookupTarget { public: mapLookupTarget(Map* m) : objectOrMapLookupTarget(m) {} public: bool EQ(lookupTarget* t) { return t->is_map() && map() == t->map(); } lookupTarget* get_target_for_slot(slotDesc* s, simpleLookup* L); protected: bool is_map() { return true; } public: void print(); }; class vframeLookupTarget: public lookupTarget { public: abstract_vframe* vf; oop receiver; vframeLookupTarget(abstract_vframe* f, oop r) : lookupTarget(f->method()->map()) { vf = f; receiver = r; } bool EQ(lookupTarget* t) { return t->is_vframe() && vf->EQ(((vframeLookupTarget*) t)->vf); } lookupTarget* get_target_for_slot(slotDesc* s, simpleLookup* L); oop get_slot(slotDesc*); void set_slot(slotDesc*, oop); protected: bool is_vframe() { return true; } public: void print(); }; # ifdef SIC_COMPILER class sicScopeLookupTarget: public lookupTarget { public: SScope* scope; sicScopeLookupTarget(SScope* s); bool EQ(lookupTarget* t) { return t->is_scope() && scope == ((sicScopeLookupTarget*) t)->scope; } lookupTarget* get_target_for_slot(slotDesc* s, simpleLookup* L); protected: bool is_scope() { return true; } public: void print(); }; # endif