Skip to content

Commit 4ed7350

Browse files
author
Thomas Schatzl
committed
8304393: Provide method to iterate over regions of humongous object in G1
Reviewed-by: iwalulya, ayang
1 parent eb73fa8 commit 4ed7350

7 files changed

+45
-52
lines changed

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -1084,9 +1084,10 @@ class G1CollectedHeap : public CollectedHeap {
10841084
inline HeapRegion* region_at(uint index) const;
10851085
inline HeapRegion* region_at_or_null(uint index) const;
10861086

1087-
// Return the next region (by index) that is part of the same
1088-
// humongous object that hr is part of.
1089-
inline HeapRegion* next_region_in_humongous(HeapRegion* hr) const;
1087+
// Iterate over the regions that the humongous object starting at the given
1088+
// region and apply the given method with the signature f(HeapRegion*) on them.
1089+
template <typename Func>
1090+
void humongous_obj_regions_iterate(HeapRegion* start, const Func& f);
10901091

10911092
// Calculate the region index of the given address. Given address must be
10921093
// within the heap.

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

+9-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,15 @@ inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at
107107
// Return the region with the given index, or NULL if unmapped. It assumes the index is valid.
108108
inline HeapRegion* G1CollectedHeap::region_at_or_null(uint index) const { return _hrm.at_or_null(index); }
109109

110-
inline HeapRegion* G1CollectedHeap::next_region_in_humongous(HeapRegion* hr) const {
111-
return _hrm.next_region_in_humongous(hr);
110+
template <typename Func>
111+
inline void G1CollectedHeap::humongous_obj_regions_iterate(HeapRegion* start, const Func& f) {
112+
assert(start->is_starts_humongous(), "must be");
113+
114+
do {
115+
HeapRegion* next = _hrm.next_region_in_humongous(start);
116+
f(start);
117+
start = next;
118+
} while (start != nullptr);
112119
}
113120

114121
inline uint G1CollectedHeap::addr_to_region(const void* addr) const {

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

+15-25
Original file line numberDiff line numberDiff line change
@@ -475,29 +475,18 @@ void G1ConcurrentMark::reset() {
475475
_root_regions.reset();
476476
}
477477

478-
void G1ConcurrentMark::clear_statistics_in_region(uint region_idx) {
478+
void G1ConcurrentMark::clear_statistics(HeapRegion* r) {
479+
uint region_idx = r->hrm_index();
479480
for (uint j = 0; j < _max_num_tasks; ++j) {
480481
_tasks[j]->clear_mark_stats_cache(region_idx);
481482
}
482483
_top_at_rebuild_starts[region_idx] = NULL;
483484
_region_mark_stats[region_idx].clear();
484485
}
485486

486-
void G1ConcurrentMark::clear_statistics(HeapRegion* r) {
487-
uint const region_idx = r->hrm_index();
488-
if (r->is_humongous()) {
489-
assert(r->is_starts_humongous(), "Got humongous continues region here");
490-
uint const size_in_regions = (uint)_g1h->humongous_obj_size_in_regions(cast_to_oop(r->humongous_start_region()->bottom())->size());
491-
for (uint j = region_idx; j < (region_idx + size_in_regions); j++) {
492-
clear_statistics_in_region(j);
493-
}
494-
} else {
495-
clear_statistics_in_region(region_idx);
496-
}
497-
}
498-
499487
void G1ConcurrentMark::humongous_object_eagerly_reclaimed(HeapRegion* r) {
500488
assert_at_safepoint();
489+
assert(r->is_starts_humongous(), "Got humongous continues region here");
501490

502491
// Need to clear mark bit of the humongous object. Doing this unconditionally is fine.
503492
mark_bitmap()->clear(r->bottom());
@@ -507,7 +496,10 @@ void G1ConcurrentMark::humongous_object_eagerly_reclaimed(HeapRegion* r) {
507496
}
508497

509498
// Clear any statistics about the region gathered so far.
510-
clear_statistics(r);
499+
_g1h->humongous_obj_regions_iterate(r,
500+
[&] (HeapRegion* r) {
501+
clear_statistics(r);
502+
});
511503
}
512504

513505
void G1ConcurrentMark::reset_marking_for_restart() {
@@ -1124,29 +1116,27 @@ class G1UpdateRemSetTrackingBeforeRebuildTask : public WorkerTask {
11241116
// Distribute the given marked bytes across the humongous object starting
11251117
// with hr and note end of marking for these regions.
11261118
void distribute_marked_bytes(HeapRegion* hr, size_t marked_bytes) {
1127-
uint const region_idx = hr->hrm_index();
1128-
11291119
size_t const obj_size_in_words = cast_to_oop(hr->bottom())->size();
1130-
uint const num_regions_in_humongous = (uint)G1CollectedHeap::humongous_obj_size_in_regions(obj_size_in_words);
11311120

11321121
// "Distributing" zero words means that we only note end of marking for these
11331122
// regions.
11341123
assert(marked_bytes == 0 || obj_size_in_words * HeapWordSize == marked_bytes,
11351124
"Marked bytes should either be 0 or the same as humongous object (%zu) but is %zu",
11361125
obj_size_in_words * HeapWordSize, marked_bytes);
11371126

1138-
for (uint i = region_idx; i < (region_idx + num_regions_in_humongous); i++) {
1139-
HeapRegion* const r = _g1h->region_at(i);
1127+
auto distribute_bytes = [&] (HeapRegion* r) {
11401128
size_t const bytes_to_add = MIN2(HeapRegion::GrainBytes, marked_bytes);
11411129

11421130
log_trace(gc, marking)("Adding %zu bytes to humongous region %u (%s)",
1143-
bytes_to_add, i, r->get_type_str());
1131+
bytes_to_add, r->hrm_index(), r->get_type_str());
11441132
add_marked_bytes_and_note_end(r, bytes_to_add);
11451133
marked_bytes -= bytes_to_add;
1146-
}
1134+
};
1135+
_g1h->humongous_obj_regions_iterate(hr, distribute_bytes);
1136+
11471137
assert(marked_bytes == 0,
1148-
"%zu bytes left after distributing space across %u regions",
1149-
marked_bytes, num_regions_in_humongous);
1138+
"%zu bytes left after distributing space across %zu regions",
1139+
marked_bytes, G1CollectedHeap::humongous_obj_size_in_regions(obj_size_in_words));
11501140
}
11511141

11521142
void update_marked_bytes(HeapRegion* hr) {
@@ -1369,7 +1359,7 @@ class G1ReclaimEmptyRegionsTask : public WorkerTask {
13691359
_g1h->free_region(hr, _local_cleanup_list);
13701360
}
13711361
hr->clear_cardtable();
1372-
_g1h->concurrent_mark()->clear_statistics_in_region(hr->hrm_index());
1362+
_g1h->concurrent_mark()->clear_statistics(hr);
13731363
}
13741364

13751365
return false;

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

+1-5
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,6 @@ class G1ConcurrentMark : public CHeapObj<mtGC> {
382382
// After reclaiming empty regions, update heap sizes.
383383
void compute_new_sizes();
384384

385-
// Clear statistics gathered during the concurrent cycle for the given region after
386-
// it has been reclaimed.
387-
void clear_statistics(HeapRegion* r);
388-
389385
// Resets all the marking data structures. Called when we have to restart
390386
// marking or when marking completes (via set_non_marking_state below).
391387
void reset_marking_for_restart();
@@ -481,7 +477,7 @@ class G1ConcurrentMark : public CHeapObj<mtGC> {
481477

482478
// Clear statistics gathered during the concurrent cycle for the given region after
483479
// it has been reclaimed.
484-
void clear_statistics_in_region(uint region_idx);
480+
void clear_statistics(HeapRegion* r);
485481
// Notification for eagerly reclaimed regions to clean up.
486482
void humongous_object_eagerly_reclaimed(HeapRegion* r);
487483
// Manipulation of the global mark stack.

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,11 @@ void G1FullGCCompactionPoint::add_humongous(HeapRegion* hr) {
138138
_collector->add_humongous_region(hr);
139139

140140
G1CollectedHeap* g1h = G1CollectedHeap::heap();
141-
do {
142-
add(hr);
143-
_collector->update_from_skip_compacting_to_compacting(hr->hrm_index());
144-
hr = g1h->next_region_in_humongous(hr);
145-
} while (hr != nullptr);
141+
g1h->humongous_obj_regions_iterate(hr,
142+
[&] (HeapRegion* r) {
143+
add(r);
144+
_collector->update_from_skip_compacting_to_compacting(r->hrm_index());
145+
});
146146
}
147147

148148
uint G1FullGCCompactionPoint::forward_humongous(HeapRegion* hr) {

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

+6-8
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,12 @@ void G1RemSetTrackingPolicy::update_after_rebuild(HeapRegion* r) {
148148
// cycle as e.g. remembered set entries will always be added.
149149
if (r->is_starts_humongous() && !g1h->is_potential_eager_reclaim_candidate(r)) {
150150
// Handle HC regions with the HS region.
151-
uint const size_in_regions = (uint)g1h->humongous_obj_size_in_regions(cast_to_oop(r->bottom())->size());
152-
uint const region_idx = r->hrm_index();
153-
for (uint j = region_idx; j < (region_idx + size_in_regions); j++) {
154-
HeapRegion* const cur = g1h->region_at(j);
155-
assert(!cur->is_continues_humongous() || cur->rem_set()->is_empty(),
156-
"Continues humongous region %u remset should be empty", j);
157-
cur->rem_set()->clear_locked(true /* only_cardset */);
158-
}
151+
g1h->humongous_obj_regions_iterate(r,
152+
[&] (HeapRegion* r) {
153+
assert(!r->is_continues_humongous() || r->rem_set()->is_empty(),
154+
"Continues humongous region %u remset should be empty", r->hrm_index());
155+
r->rem_set()->clear_locked(true /* only_cardset */);
156+
});
159157
}
160158
G1ConcurrentMark* cm = G1CollectedHeap::heap()->concurrent_mark();
161159
log_trace(gc, remset, tracking)("After rebuild region %u "

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

+5-4
Original file line numberDiff line numberDiff line change
@@ -213,15 +213,16 @@ class G1FreeHumongousRegionClosure : public HeapRegionIndexClosure {
213213
region_index,
214214
BOOL_TO_STR(cm->is_marked_in_bitmap(obj)));
215215
_humongous_objects_reclaimed++;
216-
do {
217-
HeapRegion* next = _g1h->next_region_in_humongous(r);
216+
217+
auto free_humongous_region = [&] (HeapRegion* r) {
218218
_freed_bytes += r->used();
219219
r->set_containing_set(nullptr);
220220
_humongous_regions_reclaimed++;
221221
_g1h->free_humongous_region(r, nullptr);
222222
_g1h->hr_printer()->cleanup(r);
223-
r = next;
224-
} while (r != nullptr);
223+
};
224+
225+
_g1h->humongous_obj_regions_iterate(r, free_humongous_region);
225226

226227
return false;
227228
}

0 commit comments

Comments
 (0)