@@ -174,36 +174,47 @@ class SCCompacter {
174
174
return _spaces[index]._compaction_top ;
175
175
}
176
176
177
- // Get space at index.
177
+ // Get space at index.build_
178
178
ContiguousSpace* get_space (uint index) const {
179
179
return _spaces[index]._space ;
180
180
}
181
181
182
182
// 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 ) {
184
184
if (addr >= limit) return limit;
185
185
if (!_mark_bitmap.is_marked (addr)) {
186
186
// Easy: find next marked address.
187
187
return _mark_bitmap.get_next_marked_addr (addr, limit);
188
188
} 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
- }
200
189
// 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);
204
217
}
205
- assert (current >= addr, " found object start must be >= addr" );
206
- return MIN2 (current, limit);
207
218
}
208
219
}
209
220
@@ -213,6 +224,7 @@ class SCCompacter {
213
224
HeapWord* const bottom = space->bottom ();
214
225
HeapWord* const top = space->top ();
215
226
227
+ TenuredSpace* bot_space = UseNewCode && space == SerialHeap::heap ()->old_gen ()->space () ? SerialHeap::heap ()->old_gen ()->space () : nullptr ;
216
228
// Clear table (only required for assertion in forwardee()).
217
229
DEBUG_ONLY (clear (bottom, top);)
218
230
@@ -229,7 +241,7 @@ class SCCompacter {
229
241
// Find first object that starts after this block and count
230
242
// live words up to that object. This is how many words we
231
243
// 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 );
233
245
size_t live_in_block = _mark_bitmap.count_marked_words (first_obj_this_block, first_obj_after_block);
234
246
while (live_in_block > pointer_delta (_spaces[_index]._space ->end (),
235
247
compact_top)) {
@@ -398,14 +410,16 @@ void SCCompacter::compact_space(uint idx) const {
398
410
// Visit all live objects in the space.
399
411
while (current < top) {
400
412
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.
404
414
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
+
405
419
Copy::aligned_conjoint_words (current, compact_to, size);
406
420
407
421
// 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);
409
423
}
410
424
411
425
// Reset top and unused memory
@@ -637,7 +651,7 @@ class SCKeepAliveClosure: public OopClosure {
637
651
638
652
bool SerialCompressor::mark_object (oop obj) {
639
653
HeapWord* addr = cast_from_oop<HeapWord*>(obj);
640
- if (! _mark_bitmap.is_marked (addr)) {
654
+ if (_mark_bitmap.set_mark (addr)) {
641
655
if (StringDedup::is_enabled () &&
642
656
java_lang_String::is_instance (obj) &&
643
657
SerialStringDedup::is_candidate_from_mark (obj)) {
@@ -648,7 +662,6 @@ bool SerialCompressor::mark_object(oop obj) {
648
662
// which might include important class information.
649
663
ContinuationGCSupport::transform_stack_chunk (obj);
650
664
651
- _mark_bitmap.mark_range (addr, obj->size ());
652
665
return true ;
653
666
} else {
654
667
return false ;
@@ -674,9 +687,11 @@ void SerialCompressor::follow_object(oop obj) {
674
687
assert (_mark_bitmap.is_marked (obj), " p must be marked" );
675
688
if (obj->is_objArray ()) {
676
689
follow_array ((objArrayOop)obj);
690
+ _mark_bitmap.mark_range (cast_from_oop<HeapWord*>(obj), ((objArrayOop)obj)->size ());
677
691
} else {
678
692
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);
680
695
}
681
696
}
682
697
0 commit comments