# HG changeset patch # User ehelin # Date 1422264755 -3600 # Mon Jan 26 10:32:35 2015 +0100 # Node ID d643b0c2026f85eb2f8ac9381db3ea0f60aa44a0 # Parent b59d6dde575bdfa29eb6a7b2fcd5812717270995 8030646: track collection set membership in one place diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -6072,7 +6072,7 @@ HeapRegion* next = cur->next_in_collection_set(); assert(cur->in_collection_set(), "bad CS"); cur->set_next_in_collection_set(NULL); - cur->set_in_collection_set(false); + clear_in_cset_fast_test(cur); if (cur->is_young()) { int index = cur->young_index_in_cset(); @@ -6298,7 +6298,7 @@ HeapRegion* next = cur->next_in_collection_set(); assert(cur->in_collection_set(), "bad CS"); cur->set_next_in_collection_set(NULL); - cur->set_in_collection_set(false); + clear_in_cset_fast_test(cur); cur->set_young_index_in_cset(-1); cur = next; } diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -656,6 +656,9 @@ void register_old_region_with_in_cset_fast_test(HeapRegion* r) { _in_cset_fast_test.set_in_old(r->hrm_index()); } + void clear_in_cset_fast_test(const HeapRegion* hr) { + _in_cset_fast_test.clear(hr); + } // This is a fast test on whether a reference points into the // collection set or not. Assume that the reference @@ -1245,6 +1248,7 @@ // set. Slow implementation. inline bool obj_in_cs(oop obj); + inline bool is_in_cset(const HeapRegion *hr); inline bool is_in_cset(oop obj); inline bool is_in_cset_or_humongous(const oop obj); diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp @@ -234,6 +234,10 @@ return ret; } +bool G1CollectedHeap::is_in_cset(const HeapRegion* hr) { + return _in_cset_fast_test.is_in_cset(hr); +} + bool G1CollectedHeap::is_in_cset_or_humongous(const oop obj) { return _in_cset_fast_test.is_in_cset_or_humongous((HeapWord*)obj); } diff --git a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -1617,11 +1617,10 @@ assert(hr->is_old(), "the region should be old"); assert(!hr->in_collection_set(), "should not already be in the CSet"); - hr->set_in_collection_set(true); + _g1->register_old_region_with_in_cset_fast_test(hr); hr->set_next_in_collection_set(_collection_set); _collection_set = hr; _collection_set_bytes_used_before += hr->used(); - _g1->register_old_region_with_in_cset_fast_test(hr); size_t rs_length = hr->rem_set()->occupied(); _recorded_rs_lengths += rs_length; _old_cset_region_length += 1; @@ -1751,10 +1750,8 @@ _inc_cset_max_finger = MAX2(_inc_cset_max_finger, hr_end); assert(!hr->in_collection_set(), "invariant"); - hr->set_in_collection_set(true); + _g1->register_young_region_with_in_cset_fast_test(hr); assert( hr->next_in_collection_set() == NULL, "invariant"); - - _g1->register_young_region_with_in_cset_fast_test(hr); } // Add the region at the RHS of the incremental cset diff --git a/src/share/vm/gc_implementation/g1/g1InCSetState.hpp b/src/share/vm/gc_implementation/g1/g1InCSetState.hpp --- a/src/share/vm/gc_implementation/g1/g1InCSetState.hpp +++ b/src/share/vm/gc_implementation/g1/g1InCSetState.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP +#include "gc_implementation/g1/heapRegion.hpp" #include "gc_implementation/g1/g1BiasedArray.hpp" #include "memory/allocation.hpp" @@ -125,8 +126,10 @@ bool is_in_cset_or_humongous(HeapWord* addr) const { return at(addr).is_in_cset_or_humongous(); } bool is_in_cset(HeapWord* addr) const { return at(addr).is_in_cset(); } + bool is_in_cset(const HeapRegion* hr) const { return get_by_index(hr->hrm_index()).is_in_cset(); } InCSetState at(HeapWord* addr) const { return get_by_address(addr); } void clear() { G1BiasedMappedArray::clear(); } + void clear(const HeapRegion* hr) { return set_by_index(hr->hrm_index(), InCSetState::NotInCSet); } }; #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP diff --git a/src/share/vm/gc_implementation/g1/heapRegion.cpp b/src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -162,8 +162,6 @@ "we should have already filtered out humongous regions"); assert(_end == orig_end(), "we should have already filtered out humongous regions"); - assert(!_in_collection_set, - err_msg("Should not clear heap region %u in the collection set", hrm_index())); set_allocation_context(AllocationContext::system()); set_young_index_in_cset(-1); @@ -262,7 +260,6 @@ _hrm_index(hrm_index), _allocation_context(AllocationContext::system()), _humongous_start_region(NULL), - _in_collection_set(false), _next_in_special_set(NULL), _evacuation_failed(false), _prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0), diff --git a/src/share/vm/gc_implementation/g1/heapRegion.hpp b/src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -236,8 +236,6 @@ // For a humongous region, region in which it starts. HeapRegion* _humongous_start_region; - // True iff the region is in current collection_set. - bool _in_collection_set; // True iff an attempt to evacuate an object in the region failed. bool _evacuation_failed; @@ -487,13 +485,8 @@ return _rem_set; } - // True iff the region is in current collection_set. - bool in_collection_set() const { - return _in_collection_set; - } - void set_in_collection_set(bool b) { - _in_collection_set = b; - } + bool in_collection_set() const; + HeapRegion* next_in_collection_set() { assert(in_collection_set(), "should only invoke on member of CS."); assert(_next_in_special_set == NULL || diff --git a/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp b/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp +++ b/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp @@ -195,4 +195,8 @@ } } +inline bool HeapRegion::in_collection_set() const { + return G1CollectedHeap::heap()->is_in_cset(this); +} + #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_INLINE_HPP