diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 5e8031b613dfc..d3f155debf3de 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -2285,6 +2285,10 @@ void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { _hrm.iterate(cl); } +void G1CollectedHeap::heap_region_iterate(HeapRegionIndexClosure* cl) const { + _hrm.iterate(cl); +} + void G1CollectedHeap::heap_region_par_iterate_from_worker_offset(HeapRegionClosure* cl, HeapRegionClaimer *hrclaimer, uint worker_id) const { diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 714877f909d90..45f6852094668 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -1080,6 +1080,7 @@ class G1CollectedHeap : public CollectedHeap { // Iterate over heap regions, in address order, terminating the // iteration early if the "do_heap_region" method returns "true". void heap_region_iterate(HeapRegionClosure* blk) const; + void heap_region_iterate(HeapRegionIndexClosure* blk) const; // Return the region with the given index. It assumes the index is valid. inline HeapRegion* region_at(uint index) const; diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index 5145a38fe0ad9..c6a26a1a19c60 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -609,4 +609,23 @@ class HeapRegionClosure : public StackObj { bool is_complete() { return _is_complete; } }; +class HeapRegionIndexClosure : public StackObj { + friend class HeapRegionManager; + friend class G1CollectionSet; + friend class G1CollectionSetCandidates; + + bool _is_complete; + void set_incomplete() { _is_complete = false; } + +public: + HeapRegionIndexClosure(): _is_complete(true) {} + + // Typically called on each region until it returns true. + virtual bool do_heap_region_index(uint region_index) = 0; + + // True after iteration if the closure was applied to all heap regions + // and returned "false" in all cases. + bool is_complete() { return _is_complete; } +}; + #endif // SHARE_GC_G1_HEAPREGION_HPP diff --git a/src/hotspot/share/gc/g1/heapRegionManager.cpp b/src/hotspot/share/gc/g1/heapRegionManager.cpp index 2688a2bc438a7..913d2df5017b7 100644 --- a/src/hotspot/share/gc/g1/heapRegionManager.cpp +++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp @@ -526,6 +526,21 @@ void HeapRegionManager::iterate(HeapRegionClosure* blk) const { } } +void HeapRegionManager::iterate(HeapRegionIndexClosure* blk) const { + uint len = reserved_length(); + + for (uint i = 0; i < len; i++) { + if (!is_available(i)) { + continue; + } + bool res = blk->do_heap_region_index(i); + if (res) { + blk->set_incomplete(); + return; + } + } +} + uint HeapRegionManager::find_highest_free(bool* expanded) { // Loop downwards from the highest region index, looking for an // entry which is either free or not yet committed. If not yet diff --git a/src/hotspot/share/gc/g1/heapRegionManager.hpp b/src/hotspot/share/gc/g1/heapRegionManager.hpp index 173b00b0033f3..39b6a68cbf35f 100644 --- a/src/hotspot/share/gc/g1/heapRegionManager.hpp +++ b/src/hotspot/share/gc/g1/heapRegionManager.hpp @@ -271,6 +271,7 @@ class HeapRegionManager: public CHeapObj { // Apply blk->do_heap_region() on all committed regions in address order, // terminating the iteration early if do_heap_region() returns true. void iterate(HeapRegionClosure* blk) const; + void iterate(HeapRegionIndexClosure* blk) const; void par_iterate(HeapRegionClosure* blk, HeapRegionClaimer* hrclaimer, const uint start_index) const;