Skip to content

Commit c2c6c29

Browse files
author
Thomas Schatzl
committed
split compact + adjust phase
1 parent fc07978 commit c2c6c29

File tree

1 file changed

+68
-55
lines changed

1 file changed

+68
-55
lines changed

src/hotspot/share/gc/serial/serialCompressor.cpp

Lines changed: 68 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class SCCompacter {
151151

152152
// Given a heap word (usually the start of an object), compute the forwarding address.
153153
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");
155155
HeapWord* block_base = align_down(addr, bytes_per_block());
156156
size_t block = addr_to_block_idx(addr);
157157
assert(_bot[block] != nullptr, "must have initialized BOT entry");
@@ -212,8 +212,8 @@ class SCCompacter {
212212
// Build the block-offset-table for space at index.
213213
void build_table_for_space(uint idx) {
214214
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();
217217

218218
// Clear table (only required for assertion in forwardee()).
219219
DEBUG_ONLY(clear(bottom, top);)
@@ -223,6 +223,7 @@ class SCCompacter {
223223
SCDeadSpacer dead_spacer(space);
224224

225225
HeapWord* compact_top = get_compaction_top(_index);
226+
HeapWord* const start_compact_top = compact_top;
226227
HeapWord* current = bottom;
227228

228229
// Scan all live blocks in the space.
@@ -256,6 +257,7 @@ class SCCompacter {
256257
size_t live_in_block = _mark_bitmap.count_marked_words(first_obj_this_block, first_obj_after_block);
257258
while (live_in_block > pointer_delta(_spaces[_index]._space->end(),
258259
compact_top)) {
260+
log_info(gc)("split!");
259261
// out-of-memory in this space
260262
_spaces[_index]._compaction_top = compact_top;
261263
_index++;
@@ -274,6 +276,7 @@ class SCCompacter {
274276
record_first_dead(idx, top);
275277
}
276278
_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));
277280
}
278281

279282
// Reserves memory for the block-offset-table (does not commit any memory, yet).
@@ -342,11 +345,15 @@ class SCCompacter {
342345

343346
// Compact live objects in a space.
344347
void compact_space(uint idx) const;
348+
void adjust_space(uint idx);
345349

346350
void phase3_compact() {
347351
for (uint i = 0; i < _num_spaces; ++i) {
348352
compact_space(i);
349353
}
354+
for (uint i = 0; i < _num_spaces; ++i) {
355+
adjust_space(i);
356+
}
350357
}
351358
};
352359

@@ -405,68 +412,74 @@ static ContiguousSpace* space_containing(HeapWord* addr) {
405412
// Compact live objects in a space.
406413
void SCCompacter::compact_space(uint idx) const {
407414
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();
410417
HeapWord* current = _mark_bitmap.get_next_marked_addr(bottom, top);
411418

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);
445435
}
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");
457444
// Dead-spacer object, not a record of next live object.
458445
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;
465446
}
466447
}
467448

468449
// Reset top and unused memory
469450
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+
}
470483
if (ZapUnusedHeapArea) {
471484
space->mangle_unused_area();
472485
}

0 commit comments

Comments
 (0)