@@ -174,36 +174,47 @@ class SCCompacter {
174174 return _spaces[index]._compaction_top ;
175175 }
176176
177- // Get space at index.
177+ // Get space at index.build_
178178 ContiguousSpace* get_space (uint index) const {
179179 return _spaces[index]._space ;
180180 }
181181
182182 // Find the start of the first object at or after addr (but not after limit).
183- HeapWord* first_object_in_block (HeapWord* addr, HeapWord* start, HeapWord* limit) {
183+ HeapWord* first_object_in_block (HeapWord* addr, HeapWord* start, HeapWord* limit, TenuredSpace* bot_provider ) {
184184 if (addr >= limit) return limit;
185185 if (!_mark_bitmap.is_marked (addr)) {
186186 // Easy: find next marked address.
187187 return _mark_bitmap.get_next_marked_addr (addr, limit);
188188 } else {
189- // Find beginning of live chunk.
190- HeapWord* current = _mark_bitmap.get_last_unmarked_addr (start, addr);
191- if (current == addr) {
192- // No clear bit found before search range, start of range because that must
193- // be the previous object.
194- current = start;
195- } else {
196- // Use first marked word, this must be an object.
197- assert (!_mark_bitmap.is_marked (current), " must not be marked" );
198- current = current + 1 ;
199- }
200189 // Forward-search to first object >= addr.
201- while (current < addr) {
202- size_t obj_size = cast_to_oop (current)->size ();
203- current += obj_size;
190+ if (bot_provider != nullptr ) {
191+ HeapWord* reaching_into = bot_provider->block_start_const (addr);
192+ if (reaching_into < addr) {
193+ reaching_into = reaching_into + cast_to_oop<HeapWord*>(reaching_into)->size ();
194+ }
195+ assert (reaching_into >= addr, " must be" );
196+ assert (reaching_into == limit || oopDesc::is_oop (cast_to_oop<HeapWord*>(reaching_into)), " must be" );
197+ return reaching_into;
198+ } else {
199+ // Find beginning of live chunk.
200+ HeapWord* current = _mark_bitmap.get_last_unmarked_addr (start, addr);
201+ if (current == addr) {
202+ // No clear bit found before search range, start of range because that must
203+ // be the previous object.
204+ current = start;
205+ } else {
206+ // Use first marked word, this must be an object.
207+ assert (!_mark_bitmap.is_marked (current), " must not be marked" );
208+ current = current + 1 ;
209+ }
210+
211+ while (current < addr) {
212+ size_t obj_size = cast_to_oop (current)->size ();
213+ current += obj_size;
214+ }
215+ assert (current >= addr, " found object start must be >= addr" );
216+ return MIN2 (current, limit);
204217 }
205- assert (current >= addr, " found object start must be >= addr" );
206- return MIN2 (current, limit);
207218 }
208219 }
209220
@@ -213,6 +224,7 @@ class SCCompacter {
213224 HeapWord* const bottom = space->bottom ();
214225 HeapWord* const top = space->top ();
215226
227+ TenuredSpace* bot_space = UseNewCode && space == SerialHeap::heap ()->old_gen ()->space () ? SerialHeap::heap ()->old_gen ()->space () : nullptr ;
216228 // Clear table (only required for assertion in forwardee()).
217229 DEBUG_ONLY (clear (bottom, top);)
218230
@@ -229,7 +241,7 @@ class SCCompacter {
229241 // Find first object that starts after this block and count
230242 // live words up to that object. This is how many words we
231243 // must fit into the current compaction space.
232- HeapWord* first_obj_after_block = first_object_in_block (current + words_per_block (), first_obj_this_block, top);
244+ HeapWord* first_obj_after_block = first_object_in_block (current + words_per_block (), first_obj_this_block, top, bot_space );
233245 size_t live_in_block = _mark_bitmap.count_marked_words (first_obj_this_block, first_obj_after_block);
234246 while (live_in_block > pointer_delta (_spaces[_index]._space ->end (),
235247 compact_top)) {
@@ -398,14 +410,16 @@ void SCCompacter::compact_space(uint idx) const {
398410 // Visit all live objects in the space.
399411 while (current < top) {
400412 assert (_mark_bitmap.is_marked (current), " must be marked" );
401-
402- // Copy the object.
403- size_t size = cast_to_oop (current)->size ();
413+ // Copy the whole chunk.
404414 HeapWord* compact_to = forwardee (current);
415+
416+ HeapWord* next_dead = _mark_bitmap.get_next_unmarked_addr (current, top);
417+ size_t size = pointer_delta (next_dead, current);
418+
405419 Copy::aligned_conjoint_words (current, compact_to, size);
406420
407421 // Advance to next live object.
408- current = _mark_bitmap.get_next_marked_addr (current + size , top);
422+ current = _mark_bitmap.get_next_marked_addr (next_dead , top);
409423 }
410424
411425 // Reset top and unused memory
@@ -637,7 +651,7 @@ class SCKeepAliveClosure: public OopClosure {
637651
638652bool SerialCompressor::mark_object (oop obj) {
639653 HeapWord* addr = cast_from_oop<HeapWord*>(obj);
640- if (! _mark_bitmap.is_marked (addr)) {
654+ if (_mark_bitmap.set_mark (addr)) {
641655 if (StringDedup::is_enabled () &&
642656 java_lang_String::is_instance (obj) &&
643657 SerialStringDedup::is_candidate_from_mark (obj)) {
@@ -648,7 +662,6 @@ bool SerialCompressor::mark_object(oop obj) {
648662 // which might include important class information.
649663 ContinuationGCSupport::transform_stack_chunk (obj);
650664
651- _mark_bitmap.mark_range (addr, obj->size ());
652665 return true ;
653666 } else {
654667 return false ;
@@ -674,9 +687,11 @@ void SerialCompressor::follow_object(oop obj) {
674687 assert (_mark_bitmap.is_marked (obj), " p must be marked" );
675688 if (obj->is_objArray ()) {
676689 follow_array ((objArrayOop)obj);
690+ _mark_bitmap.mark_range (cast_from_oop<HeapWord*>(obj), ((objArrayOop)obj)->size ());
677691 } else {
678692 SCMarkAndPushClosure mark_and_push_closure (ClassLoaderData::_claim_stw_fullgc_mark, *this );
679- obj->oop_iterate (&mark_and_push_closure);
693+ size_t size = obj->oop_iterate_size (&mark_and_push_closure);
694+ _mark_bitmap.mark_range (cast_from_oop<HeapWord*>(obj), size);
680695 }
681696}
682697
0 commit comments