/* Sun-$Revision: 23.14 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface // Map*'s are UNTAGGED! but mapOop's are tagged. extern "C" { void printObjectID(oop obj); void SetNumObjectIDs(int32 length); int32 getObjectID(oop obj); } class MapBase { // instance variables (must be same as for mapOop!) protected: markOop _mark; mapOop _map; }; const fint vtbl_position = sizeof(MapBase)/oopSize; class Map: public MapBase { public: // testing operations bool is_smi() { return this == Memory-> smi_map; } bool is_float() { return this == Memory->float_map; } virtual bool is_assignment() { return false; } virtual bool is_block() { return false; } virtual bool is_byteVector() { return false; } virtual bool is_map() { return false; } virtual bool is_objVector() { return false; } virtual bool is_slots() { return false; } virtual bool is_string() { return false; } virtual bool is_mirror() { return false; } virtual bool is_programmable_slots() { return false; } virtual bool is_process() { return false; } virtual bool is_vframe() { return false; } virtual bool is_method_like() { return false; } virtual bool is_killable() { return false; } virtual bool is_foreign() { return false; } virtual bool is_proxy() { return false; } virtual bool is_fctProxy() { return false; } virtual bool is_profiler() { return false; } virtual bool should_canonicalize() { return false; } virtual bool can_have_dependents() { return false; } // map comparison bool compare(Map* m); // are the two maps the same modulo block map cloning? bool equal(Map* other); // virtual pointer value VtblPtr_t vtbl_value() { return ((VtblPtr_t*) this)[vtbl_position]; } void set_vtbl_value(VtblPtr_t vtbl) { ((VtblPtr_t*) this)[vtbl_position] = vtbl; } // constructor friend Map* create_map(fint size, slotList *slots, Map *mm, oop *obj); // creation op virtual oop fill_in_slots(slotList* slist, fint slotCount) = 0; // accessors virtual fint length_slots() = 0; // number of slots in map virtual fint length_nonVM_slots(); // number of user-level slots // (assignable slots count as two) fint length_obj_slots(); // number of data slots in object virtual slotDesc* slots() { return (slotDesc*) (this + 1); } slotDesc *slot(fint i) { return slots() + i; } virtual SlotIterator *slotIterator() { return new SlotIterator(this); } protected: fint find_slot_index_binary_for(stringOop name, bool &found); fint find_slot_index_linear_for(stringOop name, bool &found); inline slotDesc* find_slot_linear(stringOop name); inline slotDesc* find_slot_binary(stringOop name); friend void findSlot_init(); public: fint find_slot_index_for(stringOop name, bool &found); virtual slotDesc* find_slot(stringOop name); slotDesc* find_nonVM_slot(stringOop name); slotDesc* find_assignee_slot( stringOop name); virtual oop get_annotation() { return Memory->objectAnnotationObj; } // Do not call set_annotation directly--you will violate the // map canonicalization invariants. Use mirror_copy_set_annotation below // instead! -- dmu 11/14/93 virtual void set_annotation(oop a) { Unused(a); } // noop, except for slotsMaps // annotation primitives virtual oop mirror_get_annotation(oop obj); virtual oop mirror_copy_set_annotation(oop obj, oop a, bool mustAllocate= false); virtual oop mirror_annotation_at(oop obj, stringOop name); // programming prims virtual oop define(oop obj, oop contents); oop add_slots_to(oop src, oop dst, bool new_only, void *FH); virtual oop copy_add_slot(oop obj, stringOop name, slotType t, oop contents, oop anno, bool mustAllocate= false); virtual oop copy_remove_slot(oop obj, stringOop name, bool mustAllocate= false); // map side of define virtual void switch_pointer(oop obj, oop* where, oop to) = 0; virtual void switch_pointer_in_map(oop* where, oop to); protected: virtual void switch_pointer_in_map_slot(slotDesc *s, oop* where, oop to); public: // used by programming prims virtual oop fix_up_method( oop obj, oop old_optimized_method, bool isOKToBashLiteralVector= false, bool mustAllocate= true, IntBList* stack_deltas = NULL); // obj array operations -- none make sense on maps virtual fint length_obj_array(oop obj) { Unused(obj); ShouldNotCallThis(); return 0; } virtual oop* obj_array(oop obj, fint which = 0) { Unused(obj); Unused(which); ShouldNotCallThis(); return NULL; } virtual oop obj_at(oop obj, fint which) { Unused(obj); Unused(which); ShouldNotCallThis(); return NULL; } virtual void obj_at_put(oop obj, fint which, oop contents) { Unused(obj); Unused(which); Unused(contents); ShouldNotCallThis(); } // byte array operations -- none make sense on maps virtual fint length_byte_array(oop obj) { Unused(obj); ShouldNotCallThis(); return 0; } virtual char* byte_array(oop obj, fint which = 0) { Unused(obj); Unused(which); ShouldNotCallThis(); return NULL; } virtual char byte_at(oop obj, fint which) { Unused(obj); Unused(which); ShouldNotCallThis(); return 0; } virtual void byte_at_put(oop obj, fint which, char contents) { Unused(obj); Unused(which); Unused(contents); ShouldNotCallThis(); } // code operations -- most don't make sense here virtual bool has_code() { return false; } virtual byteVectorOop codes() { ShouldNotCallThis(); return byteVectorOop(NULL); } virtual objVectorOop literals() { ShouldNotCallThis(); return objVectorOop(NULL); } virtual stringOop file() { ShouldNotCallThis(); return stringOop(NULL); } virtual smiOop line() { ShouldNotCallThis(); return smiOop_zero; } virtual stringOop source() { ShouldNotCallThis(); return stringOop(NULL); } virtual MethodKind kind() { ShouldNotCallThis(); return MethodKind(NULL); } // cloning operations virtual oop clone(oop obj, bool mustAllocate= true, oop genObj= NULL) = 0; virtual bool can_inline_clone() { return false; } // If this returns true, the compiler may replace _Clone by _CloneN. // This means that the actual definition of clone() is ignored!! virtual oop cloneSize(oop obj, fint length, bool mustAllocate= true, oop filler= NULL); virtual Map* initialize() { return this; } virtual void init(stringOop name, slotsOop method) { Unused(name); Unused(method); SilenceOverrideWarning(); } // mirror operations virtual mirrorOop mirror_proto() = 0; virtual oop mirror_reflectee(oop r) { return r; } virtual oop mirror_codes(oop r); virtual oop mirror_literals(oop r); virtual oop mirror_source(oop r); virtual oop mirror_source_length(oop r); virtual oop mirror_source_offset(oop r); virtual oop mirror_file(oop r); virtual oop mirror_line(oop r); virtual oop mirror_names(oop r); virtual oop mirror_name_at(oop obj, smi inx); virtual oop mirror_contents_at(oop r, stringOop name); virtual oop mirror_is_parent_at(oop r, stringOop name); virtual oop mirror_is_argument_at(oop r, stringOop name); virtual oop mirror_is_assignable_at(oop r, stringOop name); virtual oop mirror_sender(oop r); virtual oop mirror_parent(oop r); virtual oop mirror_selector(oop r); virtual oop mirror_bci(oop r); virtual oop mirror_receiver(oop r); virtual oop mirror_expr_stack(oop r); virtual oop mirror_methodHolder(oop r); // profiler operation, returns a dummy object matching this map virtual oop dummy_obj(oop filler) = 0; // allocation operations virtual fint size() = 0; // size of map virtual fint empty_object_size() = 0; // size of obj if no slots virtual fint object_size(oop obj) = 0; // size of obj (incl. mark etc) virtual fint object_byte_size(oop obj) { // size of obj (incl. mark and return object_size(obj) * oopSize; } // bytes area, in bytes) // number of arguments this object takes (0 if not a method) virtual fint arg_count() { return 0; } protected: Map *allocInit(mapOop new_map) { return new_map == mapOop(failedAllocationOop) ? NULL : new_map->addr()->initialize(); } public: Map* copy(bool mustAllocate= true, oop genObj= NULL) { // return a copy of the receiver return allocInit( as_mapOop(this)->copy(size(), mustAllocate, genObj) ); } Map* grow(fint delta, bool mustAllocate= true) { // return a copy of the receiver with delta new slots at the end return allocInit( as_mapOop(this)->grow(size(), delta * sizeof(slotDesc)/oopSize, mustAllocate) ); } Map* insert(fint index, bool mustAllocate= true) { // return a copy of the receiver with a new slot inserted at index return allocInit( as_mapOop(this)->insert(size(), (oop*)slot(index) - (oop*)this, sizeof(slotDesc) / oopSize, mustAllocate)); } Map* remove(slotDesc* slot, fint delta, bool mustAllocate= true) { // return a copy of the receiver without this slot return allocInit( as_mapOop(this)->remove(size(), (oop*) slot - (oop*) this, delta * sizeof(slotDesc)/oopSize, mustAllocate)); } // memory operations virtual bool verify(oop obj) = 0; virtual bool verifyBytesPart(oop obj, char*& b); virtual oop scavenge(oop obj) = 0; virtual void delete_map() {} virtual void shift_map(Map* target) { Unused(target); } virtual void gc_mark_contents(oop p) { Unused(p); } // do nothing by default virtual void fixup() { initialize(); } // killable operations virtual void kill(oop p) { Unused(p); ShouldNotCallThis(); } virtual bool is_live(oop p) { Unused(p); ShouldNotCallThis(); return false;} virtual int32 debug_size(oop p) { Unused(p); return 0; } // printing operations virtual void print_string(oop obj, char* buf); virtual void print_oop(oop obj); virtual void print(oop obj); virtual void print_objVector(oop obj) { Unused(obj); } virtual void print_byteVector(oop obj) { Unused(obj); } virtual void print_code(oop obj) { Unused(obj); } void print_map() { print(as_mapOop(this)); } // primitive enumeration operations: bool has_assignment_slots(); bool matching_slots_data(oop match); bool matching_slots_name(oop match); bool matching_slots_assignment_name(oop match); virtual bool is_enumerable(oop obj, oop* matching_cell) = 0; }; // Because repeated searches for the same selector are common, // we cache the unary selector corresponding to the last searched-for // 1arg keyword selector. class FindSlotCache { private: stringOop last1ArgKW, lastUnary; public: FindSlotCache() { clear(); } void clear() { last1ArgKW= lastUnary= stringOop(badOop); } inline bool checkFor1ArgKW(stringOop name, stringOop &unary); bool verify(); }; extern FindSlotCache findSlotCache;