/* Sun-$Revision: 23.5 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface extern "C" { // enumeration: the next two are coded in assember for speed oop* find_this_object(oop* middle); // for ( ; !(*middle)->is_mark(); --middle) return middle; oop* find_next_object(oop* middle); // for ( ++middle; !(*middle)->is_mark(); ++middle) return middle; oop* find_prior_reference(oop* middle, oop target); // for ( ; (*middle) != target; --middle) return middle; } struct memOopClass: oopClass { // instance variable // markOop _mark; // moved up to oopClass to avoid C++ bogosity of uneeded dummy in this struct // --dmu 7/91 mapOop _map; // add_families_1 relies on the layout of this class: // friend void enumeration_list::add_families_1(oop* bottom, oop* top); // constructor friend memOop as_memOop(void* p) { return memOop(int32(p) + Mem_Tag); } // "destructor" memOopClass* addr() { return (memOopClass*) (int32(this) - Mem_Tag); } // space operations, is_old/new work since oop > pointer! bool is_old() { return (char*)this >= Memory->old_gen->low_boundary; } bool is_new() { return (char*)this < Memory->new_gen->high_boundary; } memOop relocate() { return Memory->relocate(this); } // memOop marking (to mark beginning of object if forwarded, // and DerivedPointers are allowed) friend memOop mark_memOop(memOop p) { int32 bits = (int32) p; assert(!isSet(bits, BitsPerWord - 1), "shouldn't have the high-order bit set"); setNth(bits, BitsPerWord - 1); assert(isSet(bits, BitsPerWord - 1), "should have the high-order bit set"); return memOop(bits); } friend memOop unmark_memOop(memOop p) { int32 bits = (int32) p; assert(isSet(bits, BitsPerWord - 1), "should have the high-order bit set"); clearNth(bits, BitsPerWord - 1); assert(!isSet(bits, BitsPerWord - 1), "shouldn't have the high-order bit set"); return memOop(bits); } friend bool is_marked_memOop(memOop p) { int32 bits = (int32) p; return isSet(bits, BitsPerWord - 1); } // mark accessors markOop mark() { return addr()->_mark; } void set_mark(markOop m) { addr()->_mark = m; } void set_mark(memOop p) { set_mark(markOop(mark_memOop(p))); } memOop mark_as_memOop() { assert(mark()->is_mem(), "mark isn't a forwarding memOop"); return unmark_memOop(memOop(mark())); } bool is_mark_as_memOop() { markOop m = mark(); return m->is_mem() && is_marked_memOop(memOop(m)); } // map accessors Map* map() { return (Map*) memOop(addr()->_map)->addr(); } void set_map(Map* m, bool cs = true) { // mp must be memOop becuase of include file order memOop mp = as_memOop(m); if (cs) Memory->store((oop*)&addr()->_map, mp); else addr()->_map = (mapOop)mp; } void set_canonical_map(Map* new_map); void canonicalize_map(); // mark ops // use this after a copy to get a new mark void init_mark() { set_mark(initial_markOop); } // mark operations inline smi identity_hash(); // inlined in memOop.h void set_identity_hash(smi); bool is_marked() { return mark()->is_marked(); } void set_mark() { set_mark(mark()->mark()); } void clear_mark() { set_mark(mark()->unmark()); } // memory operations oop scavenge(); bool verify(); bool verify_oop(bool expectErrorObj = false); void print_oop(); void print_string(char* buf); // forwarding operations bool is_forwarded() { return is_mark_as_memOop(); } void forward_to(memOop p) { assert(p->is_mem(), "forwarding to something that's not a memOop"); set_mark(p); } memOop forwardee() { return mark_as_memOop(); } // marking operations bool is_gc_marked() { return is_mark_as_memOop(); } void gc_forward_to(oTableEntry* p) { set_mark(as_memOop(p)); } memOop gc_forwardee() { return mark_as_memOop(); } oTableEntry* as_oTableEntry() { return (oTableEntry*) addr(); } // garbage collection operations inline oop gc_mark(); // inlined in memOop.h inline oop gc_mark_derived(oop* ptr, int32 offset); inline oop gc_unmark(); inline oop gc_unmark_derived(oop* ptr); void gc_moved() { oTableEntry* e = gc_forwardee()->as_oTableEntry(); e->obj = this; set_mark(e->mark); } // derived pointer support int32 compute_derived_offset(); friend bool is_object_start(oop p) { assert(((int)p & 0xffffff00) != 0x21212100, "catching a bug!"); return p->is_mark() || p->is_mem() && is_marked_memOop(memOop(p)); } int32 derived_offset() { assert(((int)this & 0xffffff00) != 0x21212100, "bug catching"); return is_object_start(mark()) ? 0 : compute_derived_offset(); } // compiler support friend int32 map_offset() { // byte offset from a tagged memOop (i.e. returns 3) return int32(&memOop(NULL)->addr()->_map); } };