Skip to content
Permalink
Browse files
8267562: G1: Missing BOT in Open Archive regions causes long pauses
Reviewed-by: tschatzl, mli
  • Loading branch information
Jiangli Zhou committed Jun 1, 2021
1 parent 2b33835 commit b17b11eb178d7aab84517771e5afc03b40095cd0
Showing 8 changed files with 57 additions and 18 deletions.
@@ -2047,6 +2047,18 @@ void FileMapInfo::fixup_mapped_heap_regions() {
assert(open_archive_heap_ranges != NULL, "NULL open_archive_heap_ranges array with non-zero count");
G1CollectedHeap::heap()->fill_archive_regions(open_archive_heap_ranges,
num_open_archive_heap_ranges);

// Populate the open archive regions' G1BlockOffsetTableParts. That ensures
// fast G1BlockOffsetTablePart::block_start operations for any given address
// within the open archive regions when trying to find start of an object
// (e.g. during card table scanning).
//
// This is only needed for open archive regions but not the closed archive
// regions, because objects in closed archive regions never reference objects
// outside the closed archive regions and they are immutable. So we never
// need their BOT during garbage collection.
G1CollectedHeap::heap()->populate_archive_regions_bot_part(open_archive_heap_ranges,
num_open_archive_heap_ranges);
}
}

@@ -82,6 +82,19 @@ G1BlockOffsetTablePart::G1BlockOffsetTablePart(G1BlockOffsetTable* array, HeapRe
{
}

void G1BlockOffsetTablePart::update() {
HeapWord* next_addr = _hr->bottom();
HeapWord* const limit = _hr->top();

HeapWord* prev_addr;
while (next_addr < limit) {
prev_addr = next_addr;
next_addr = prev_addr + block_size(prev_addr);
alloc_block(prev_addr, next_addr);
}
assert(next_addr == limit, "Should stop the scan at the limit.");
}

// The arguments follow the normal convention of denoting
// a right-open interval: [start, end)
void G1BlockOffsetTablePart:: set_remainder_to_point_to_start(HeapWord* start, HeapWord* end) {
@@ -185,6 +185,8 @@ class G1BlockOffsetTablePart {
// The elements of the array are initialized to zero.
G1BlockOffsetTablePart(G1BlockOffsetTable* array, HeapRegion* hr);

void update();

void verify() const;

// Returns the address of the start of the block containing "addr", or
@@ -712,6 +712,27 @@ inline HeapWord* G1CollectedHeap::attempt_allocation(size_t min_word_size,
return result;
}

void G1CollectedHeap::populate_archive_regions_bot_part(MemRegion* ranges, size_t count) {
assert(!is_init_completed(), "Expect to be called at JVM init time");
assert(ranges != NULL, "MemRegion array NULL");
assert(count != 0, "No MemRegions provided");

HeapWord* st = ranges[0].start();
HeapWord* last = ranges[count-1].last();
HeapRegion* hr_st = _hrm.addr_to_region(st);
HeapRegion* hr_last = _hrm.addr_to_region(last);

HeapRegion* hr_curr = hr_st;
while (hr_curr != NULL) {
hr_curr->update_bot();
if (hr_curr != hr_last) {
hr_curr = _hrm.next_region_in_heap(hr_curr);
} else {
hr_curr = NULL;
}
}
}

void G1CollectedHeap::dealloc_archive_regions(MemRegion* ranges, size_t count) {
assert(!is_init_completed(), "Expect to be called at JVM init time");
assert(ranges != NULL, "MemRegion array NULL");
@@ -740,6 +740,10 @@ class G1CollectedHeap : public CollectedHeap {
// alloc_archive_regions, and after class loading has occurred.
void fill_archive_regions(MemRegion* range, size_t count);

// Populate the G1BlockOffsetTablePart for archived regions with the given
// memory ranges.
void populate_archive_regions_bot_part(MemRegion* range, size_t count);

// For each of the specified MemRegions, uncommit the containing G1 regions
// which had been allocated by alloc_archive_regions. This should be called
// rather than fill_archive_regions at JVM init time if the archive file
@@ -84,7 +84,7 @@ bool G1FullGCPrepareTask::G1CalculatePointersClosure::do_heap_region(HeapRegion*
// lack BOT information for performance reasons.
// Recreate BOT information of high live ratio young regions here to keep expected
// performance during scanning their card tables in the collection pauses later.
update_bot(hr);
hr->update_bot();
}
log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT,
hr->hrm_index(), _collector->live_words(hr->hrm_index()));
@@ -146,22 +146,6 @@ bool G1FullGCPrepareTask::G1CalculatePointersClosure::should_compact(HeapRegion*
return live_words <= live_words_threshold;
}

void G1FullGCPrepareTask::G1CalculatePointersClosure::update_bot(HeapRegion* hr) {
HeapWord* const limit = hr->top();
HeapWord* next_addr = hr->bottom();
HeapWord* threshold = hr->initialize_threshold();
HeapWord* prev_addr;
while (next_addr < limit) {
prev_addr = next_addr;
next_addr = _bitmap->get_next_marked_addr(next_addr + 1, limit);

if (next_addr > threshold) {
threshold = hr->cross_threshold(prev_addr, next_addr);
}
}
assert(next_addr == limit, "Should stop the scan at the limit.");
}

void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(HeapRegion* hr) {
hr->rem_set()->clear();
hr->clear_cardtable();
@@ -63,7 +63,6 @@ class G1FullGCPrepareTask : public G1FullGCTask {
bool should_compact(HeapRegion* hr);
void prepare_for_compaction(HeapRegion* hr);
void prepare_for_compaction_work(G1FullGCCompactionPoint* cp, HeapRegion* hr);
void update_bot(HeapRegion* hr);

void reset_region_metadata(HeapRegion* hr);

@@ -194,6 +194,10 @@ class HeapRegion : public CHeapObj<mtGC> {
_bot_part.reset_bot();
}

void update_bot() {
_bot_part.update();
}

private:
// The remembered set for this region.
HeapRegionRemSet* _rem_set;

1 comment on commit b17b11e

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on b17b11e Jun 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.