@@ -151,7 +151,7 @@ class SCCompacter {
151
151
152
152
// Given a heap word (usually the start of an object), compute the forwarding address.
153
153
inline HeapWord* forwardee (HeapWord* addr) const {
154
- assert (_mark_bitmap.is_marked (addr), " must be marked" );
154
+ // assert(_mark_bitmap.is_marked(addr), "must be marked");
155
155
HeapWord* block_base = align_down (addr, bytes_per_block ());
156
156
size_t block = addr_to_block_idx (addr);
157
157
assert (_bot[block] != nullptr , " must have initialized BOT entry" );
@@ -212,8 +212,8 @@ class SCCompacter {
212
212
// Build the block-offset-table for space at index.
213
213
void build_table_for_space (uint idx) {
214
214
ContiguousSpace* space = get_space (idx);
215
- HeapWord* bottom = space->bottom ();
216
- HeapWord* top = space->top ();
215
+ HeapWord* const bottom = space->bottom ();
216
+ HeapWord* const top = space->top ();
217
217
218
218
// Clear table (only required for assertion in forwardee()).
219
219
DEBUG_ONLY (clear (bottom, top);)
@@ -223,6 +223,7 @@ class SCCompacter {
223
223
SCDeadSpacer dead_spacer (space);
224
224
225
225
HeapWord* compact_top = get_compaction_top (_index);
226
+ HeapWord* const start_compact_top = compact_top;
226
227
HeapWord* current = bottom;
227
228
228
229
// Scan all live blocks in the space.
@@ -256,6 +257,7 @@ class SCCompacter {
256
257
size_t live_in_block = _mark_bitmap.count_marked_words (first_obj_this_block, first_obj_after_block);
257
258
while (live_in_block > pointer_delta (_spaces[_index]._space ->end (),
258
259
compact_top)) {
260
+ log_info (gc)(" split!" );
259
261
// out-of-memory in this space
260
262
_spaces[_index]._compaction_top = compact_top;
261
263
_index++;
@@ -274,6 +276,7 @@ class SCCompacter {
274
276
record_first_dead (idx, top);
275
277
}
276
278
_spaces[_index]._compaction_top = compact_top;
279
+ // log_info(gc)("compacted [" PTR_FORMAT ", " PTR_FORMAT ") to [" PTR_FORMAT " to " PTR_FORMAT ")", p2i(bottom), p2i(top), p2i(start_compact_top), p2i(compact_top));
277
280
}
278
281
279
282
// Reserves memory for the block-offset-table (does not commit any memory, yet).
@@ -342,11 +345,15 @@ class SCCompacter {
342
345
343
346
// Compact live objects in a space.
344
347
void compact_space (uint idx) const ;
348
+ void adjust_space (uint idx);
345
349
346
350
void phase3_compact () {
347
351
for (uint i = 0 ; i < _num_spaces; ++i) {
348
352
compact_space (i);
349
353
}
354
+ for (uint i = 0 ; i < _num_spaces; ++i) {
355
+ adjust_space (i);
356
+ }
350
357
}
351
358
};
352
359
@@ -405,68 +412,74 @@ static ContiguousSpace* space_containing(HeapWord* addr) {
405
412
// Compact live objects in a space.
406
413
void SCCompacter::compact_space (uint idx) const {
407
414
ContiguousSpace* space = get_space (idx);
408
- HeapWord* bottom = space->bottom ();
409
- HeapWord* top = space->top ();
415
+ HeapWord* const bottom = space->bottom ();
416
+ HeapWord* const top = space->top ();
410
417
HeapWord* current = _mark_bitmap.get_next_marked_addr (bottom, top);
411
418
412
- SCUpdateRefsClosure cl (*this );
413
-
414
- TenuredSpace* tenured_space = SerialHeap::heap ()->old_gen ()->space ();
415
-
416
- HeapWord* last_compact_end = nullptr ;
417
-
418
- // Visit all live objects in the space.
419
- while (current < top) {
420
- assert (_mark_bitmap.is_marked (current), " must be marked" );
421
- // Copy the whole chunk.
422
- HeapWord* compact_to = forwardee (current);
423
- HeapWord* next_dead = _mark_bitmap.get_next_unmarked_addr (current, top);
424
- size_t size = pointer_delta (next_dead, current);
425
- if (compact_to != current) {
426
- assert (last_compact_end == nullptr || current < get_first_dead (idx) || compact_to == last_compact_end || space_containing (last_compact_end) != space_containing (compact_to),
427
- " must compact without gaps, except when switching spaces: current: " PTR_FORMAT " , first_dead: " PTR_FORMAT " , compact_to: " PTR_FORMAT " , last_compact_end: " PTR_FORMAT, p2i (current), p2i (get_first_dead (idx)), p2i (compact_to), p2i (last_compact_end));
428
- Copy::aligned_conjoint_words (current, compact_to, size);
429
- }
430
- last_compact_end = compact_to + size;
431
-
432
- // Scan all consecutive live objects in the current live chunk and update their references.
433
- HeapWord* obj_start = compact_to;
434
- while (obj_start < last_compact_end) {
435
- oop obj = cast_to_oop (obj_start);
436
- // Update references of object.
437
- obj->oop_iterate (&cl);
438
-
439
- // We need to update the offset table so that the beginnings of objects can be
440
- // found during scavenge. Note that we are updating the offset table based on
441
- // where the object will be once the compaction phase finishes.
442
- HeapWord* next_obj = obj_start + obj->size ();
443
- if (tenured_space->is_in_reserved (obj_start)) {
444
- tenured_space->update_for_block (obj_start, next_obj);
419
+ // log_info(gc)("compact_space [" PTR_FORMAT ", " PTR_FORMAT ")", p2i(bottom), p2i(top));
420
+ HeapWord* last_compact_end = nullptr ;
421
+ {
422
+ GCTraceTime (Info, gc) x (" Move objects" );
423
+
424
+ // Visit all live objects in the space.
425
+ while (current < top) {
426
+ assert (_mark_bitmap.is_marked (current), " must be marked" );
427
+ // Copy the whole chunk.
428
+ HeapWord* compact_to = forwardee (current);
429
+ HeapWord* next_dead = _mark_bitmap.get_next_unmarked_addr (current, top);
430
+ size_t size = pointer_delta (next_dead, current);
431
+ if (compact_to != current) {
432
+ assert (last_compact_end == nullptr || current < get_first_dead (idx) || compact_to == last_compact_end || space_containing (last_compact_end) != space_containing (compact_to),
433
+ " must compact without gaps, except when switching spaces: current: " PTR_FORMAT " , first_dead: " PTR_FORMAT " , compact_to: " PTR_FORMAT " , last_compact_end: " PTR_FORMAT, p2i (current), p2i (get_first_dead (idx)), p2i (compact_to), p2i (last_compact_end));
434
+ Copy::aligned_conjoint_words (current, compact_to, size);
445
435
}
446
-
447
- // Advance to next object in chunk.
448
- obj_start = next_obj;
449
- }
450
-
451
- // Advance to next live object.
452
- if (next_dead >= top) {
453
- break ;
454
- }
455
- assert (!_mark_bitmap.is_marked (next_dead), " must not be live" );
456
- if (next_dead < get_first_dead (idx)) {
436
+ last_compact_end = compact_to + size;
437
+
438
+ // Advance to next live object.
439
+ if (next_dead >= top) {
440
+ break ;
441
+ }
442
+ assert (!_mark_bitmap.is_marked (next_dead), " must not be live" );
443
+ assert (next_dead < get_first_dead (idx), " must be, deadspacer not supoprted" );
457
444
// Dead-spacer object, not a record of next live object.
458
445
current = _mark_bitmap.get_next_marked_addr (next_dead, top);
459
- } else {
460
- // We stored the address of the next live object in the first unmarked word
461
- // after the current live chunk.
462
- HeapWord* next = *(HeapWord**)next_dead;
463
- assert (next == _mark_bitmap.get_next_marked_addr (next_dead, top), " must match" );
464
- current = next;
465
446
}
466
447
}
467
448
468
449
// Reset top and unused memory
469
450
space->set_top (get_compaction_top (idx));
451
+ }
452
+
453
+ void SCCompacter::adjust_space (uint idx) {
454
+ // Scan all consecutive live objects in the current live chunk and update their references.
455
+ ContiguousSpace* space = get_space (idx);
456
+ {
457
+ GCTraceTime (Info, gc) a (" Adjust pointers" );
458
+ SCUpdateRefsClosure cl (*this );
459
+
460
+ TenuredSpace* tenured_space = SerialHeap::heap ()->old_gen ()->space ();
461
+ bool needs_bot_update = space == tenured_space;
462
+ HeapWord* obj_start = space->bottom ();
463
+ HeapWord* obj_top = space->top ();
464
+ // log_info(gc)("Adjust [" PTR_FORMAT ", " PTR_FORMAT ")", p2i(obj_start), p2i(obj_top));
465
+
466
+ while (obj_start < obj_top) {
467
+ oop obj = cast_to_oop (obj_start);
468
+ // Update references of object.
469
+ obj->oop_iterate (&cl);
470
+
471
+ // We need to update the offset table so that the beginnings of objects can be
472
+ // found during scavenge. Note that we are updating the offset table based on
473
+ // where the object will be once the compaction phase finishes.
474
+ HeapWord* next_obj = obj_start + obj->size ();
475
+ if (needs_bot_update) {
476
+ tenured_space->update_for_block (obj_start, next_obj);
477
+ }
478
+
479
+ // Advance to next object in chunk.
480
+ obj_start = next_obj;
481
+ }
482
+ }
470
483
if (ZapUnusedHeapArea) {
471
484
space->mangle_unused_area ();
472
485
}
0 commit comments