Skip to content

Commit b17b11e

Browse files
committed
8267562: G1: Missing BOT in Open Archive regions causes long pauses
Reviewed-by: tschatzl, mli
1 parent 2b33835 commit b17b11e

8 files changed

+57
-18
lines changed

src/hotspot/share/cds/filemap.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,18 @@ void FileMapInfo::fixup_mapped_heap_regions() {
20472047
assert(open_archive_heap_ranges != NULL, "NULL open_archive_heap_ranges array with non-zero count");
20482048
G1CollectedHeap::heap()->fill_archive_regions(open_archive_heap_ranges,
20492049
num_open_archive_heap_ranges);
2050+
2051+
// Populate the open archive regions' G1BlockOffsetTableParts. That ensures
2052+
// fast G1BlockOffsetTablePart::block_start operations for any given address
2053+
// within the open archive regions when trying to find start of an object
2054+
// (e.g. during card table scanning).
2055+
//
2056+
// This is only needed for open archive regions but not the closed archive
2057+
// regions, because objects in closed archive regions never reference objects
2058+
// outside the closed archive regions and they are immutable. So we never
2059+
// need their BOT during garbage collection.
2060+
G1CollectedHeap::heap()->populate_archive_regions_bot_part(open_archive_heap_ranges,
2061+
num_open_archive_heap_ranges);
20502062
}
20512063
}
20522064

src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,19 @@ G1BlockOffsetTablePart::G1BlockOffsetTablePart(G1BlockOffsetTable* array, HeapRe
8282
{
8383
}
8484

85+
void G1BlockOffsetTablePart::update() {
86+
HeapWord* next_addr = _hr->bottom();
87+
HeapWord* const limit = _hr->top();
88+
89+
HeapWord* prev_addr;
90+
while (next_addr < limit) {
91+
prev_addr = next_addr;
92+
next_addr = prev_addr + block_size(prev_addr);
93+
alloc_block(prev_addr, next_addr);
94+
}
95+
assert(next_addr == limit, "Should stop the scan at the limit.");
96+
}
97+
8598
// The arguments follow the normal convention of denoting
8699
// a right-open interval: [start, end)
87100
void G1BlockOffsetTablePart:: set_remainder_to_point_to_start(HeapWord* start, HeapWord* end) {

src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ class G1BlockOffsetTablePart {
185185
// The elements of the array are initialized to zero.
186186
G1BlockOffsetTablePart(G1BlockOffsetTable* array, HeapRegion* hr);
187187

188+
void update();
189+
188190
void verify() const;
189191

190192
// Returns the address of the start of the block containing "addr", or

src/hotspot/share/gc/g1/g1CollectedHeap.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,27 @@ inline HeapWord* G1CollectedHeap::attempt_allocation(size_t min_word_size,
712712
return result;
713713
}
714714

715+
void G1CollectedHeap::populate_archive_regions_bot_part(MemRegion* ranges, size_t count) {
716+
assert(!is_init_completed(), "Expect to be called at JVM init time");
717+
assert(ranges != NULL, "MemRegion array NULL");
718+
assert(count != 0, "No MemRegions provided");
719+
720+
HeapWord* st = ranges[0].start();
721+
HeapWord* last = ranges[count-1].last();
722+
HeapRegion* hr_st = _hrm.addr_to_region(st);
723+
HeapRegion* hr_last = _hrm.addr_to_region(last);
724+
725+
HeapRegion* hr_curr = hr_st;
726+
while (hr_curr != NULL) {
727+
hr_curr->update_bot();
728+
if (hr_curr != hr_last) {
729+
hr_curr = _hrm.next_region_in_heap(hr_curr);
730+
} else {
731+
hr_curr = NULL;
732+
}
733+
}
734+
}
735+
715736
void G1CollectedHeap::dealloc_archive_regions(MemRegion* ranges, size_t count) {
716737
assert(!is_init_completed(), "Expect to be called at JVM init time");
717738
assert(ranges != NULL, "MemRegion array NULL");

src/hotspot/share/gc/g1/g1CollectedHeap.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,10 @@ class G1CollectedHeap : public CollectedHeap {
740740
// alloc_archive_regions, and after class loading has occurred.
741741
void fill_archive_regions(MemRegion* range, size_t count);
742742

743+
// Populate the G1BlockOffsetTablePart for archived regions with the given
744+
// memory ranges.
745+
void populate_archive_regions_bot_part(MemRegion* range, size_t count);
746+
743747
// For each of the specified MemRegions, uncommit the containing G1 regions
744748
// which had been allocated by alloc_archive_regions. This should be called
745749
// rather than fill_archive_regions at JVM init time if the archive file

src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp

+1-17
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ bool G1FullGCPrepareTask::G1CalculatePointersClosure::do_heap_region(HeapRegion*
8484
// lack BOT information for performance reasons.
8585
// Recreate BOT information of high live ratio young regions here to keep expected
8686
// performance during scanning their card tables in the collection pauses later.
87-
update_bot(hr);
87+
hr->update_bot();
8888
}
8989
log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT,
9090
hr->hrm_index(), _collector->live_words(hr->hrm_index()));
@@ -146,22 +146,6 @@ bool G1FullGCPrepareTask::G1CalculatePointersClosure::should_compact(HeapRegion*
146146
return live_words <= live_words_threshold;
147147
}
148148

149-
void G1FullGCPrepareTask::G1CalculatePointersClosure::update_bot(HeapRegion* hr) {
150-
HeapWord* const limit = hr->top();
151-
HeapWord* next_addr = hr->bottom();
152-
HeapWord* threshold = hr->initialize_threshold();
153-
HeapWord* prev_addr;
154-
while (next_addr < limit) {
155-
prev_addr = next_addr;
156-
next_addr = _bitmap->get_next_marked_addr(next_addr + 1, limit);
157-
158-
if (next_addr > threshold) {
159-
threshold = hr->cross_threshold(prev_addr, next_addr);
160-
}
161-
}
162-
assert(next_addr == limit, "Should stop the scan at the limit.");
163-
}
164-
165149
void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(HeapRegion* hr) {
166150
hr->rem_set()->clear();
167151
hr->clear_cardtable();

src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ class G1FullGCPrepareTask : public G1FullGCTask {
6363
bool should_compact(HeapRegion* hr);
6464
void prepare_for_compaction(HeapRegion* hr);
6565
void prepare_for_compaction_work(G1FullGCCompactionPoint* cp, HeapRegion* hr);
66-
void update_bot(HeapRegion* hr);
6766

6867
void reset_region_metadata(HeapRegion* hr);
6968

src/hotspot/share/gc/g1/heapRegion.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ class HeapRegion : public CHeapObj<mtGC> {
194194
_bot_part.reset_bot();
195195
}
196196

197+
void update_bot() {
198+
_bot_part.update();
199+
}
200+
197201
private:
198202
// The remembered set for this region.
199203
HeapRegionRemSet* _rem_set;

0 commit comments

Comments
 (0)