inline void copy_oops(oop* from, oop* to, int count) { copy_oops_up(from, to, count); }
inline void copy_oops_overlapping(oop* from, oop* to, int count) { if (from < to) copy_oops_down(from + count, to + count, count); else if (from > to) copy_oops_up(from, to, count); }
void space::compact(mapOop unmarked_map_map, space*& copySpace, oop*& d, oop*& bd) { // compact oops and bytes (outwards in), place copies in copySpace // (and successors, if necessary) // Leave sentinel at end of oops part // (utilises extra word between objs and bytes part). // This causes the is_object_start() loop below to exit. set_objs_top_sentinel(badOop); if (copySpace == this) { d= objs_bottom; bd= bytes_top; } for (oop* p= objs_bottom; p < objs_top; ) { oopsOop obj = as_oopsOop(p); if (obj->is_gc_marked()) { // object survives GC // figure out size Map* nm = mapOop(obj->map()->enclosing_mapOop()->gc_unmark())->map_addr(); fint size = nm->object_size(obj); byteVectorOop bv= NULL; int32 bsize= 0; if (nm->is_byteVector()) { bv= byteVectorOop(obj); bsize= bv->lengthWords(); } if (copySpace != this && !copySpace->would_fit(size, bsize)) { copySpace= ((oldSpace*)copySpace)->next_space; d= copySpace->objs_bottom; bd= copySpace->bytes_top; } // check for special map processing if (obj->map() == Memory->map_map) { // adjust dependencies first as_mapOop(p)->map_addr()->shift_map(as_mapOop(d)->map_addr()); } // do compaction if (bv) { // compact bytes part up oop* bp = (oop*) bv->bytes(); assert(copySpace != this || bp + bsize <= bd, "bytes parts aren't in order"); copy_words_down((int32*)bp + bsize, (int32*)bd, bsize); bd -= bsize; bv->set_bytes((char*) bd); } // compact oops part down copy_oops_up(p, d, size); as_oopsOop(d)->gc_moved(); d += size; p += size; if (copySpace != this) { copySpace->objs_top= d; copySpace->bytes_bottom= bd; } } else { // object is dying // check for special map processing if (((memOopClass*)p)->_map == unmarked_map_map) { // delete the dying map as_mapOop(p)->map_addr()->delete_map(); } // skip to next object // (can't use object's map to compute object size, // since it might be destroyed by now) for (p += 2; // skip mark and map !is_object_start(*p); p++) ; assert(p <= objs_top, "compacter ran off end"); } } assert(d < bd, "didn't compact anything"); if (copySpace == this) { objs_top= d; bytes_bottom= bd; } }