--- old/src/share/vm/gc/g1/g1CollectionSet.cpp 2016-06-28 14:13:04.957422199 +0200 +++ new/src/share/vm/gc/g1/g1CollectionSet.cpp 2016-06-28 14:13:04.861419307 +0200 @@ -26,7 +26,6 @@ #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1CollectionSet.hpp" #include "gc/g1/g1CollectorState.hpp" -#include "gc/g1/g1FixedSizeStack.inline.hpp" #include "gc/g1/g1Policy.hpp" #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" @@ -57,9 +56,11 @@ _eden_region_length(0), _survivor_region_length(0), _old_region_length(0), - _collection_set_regions(), _bytes_used_before(0), _recorded_rs_lengths(0), + _collection_set_regions(NULL), + _collection_set_cur_length(0), + _collection_set_max_length(0), // Incremental CSet attributes _inc_build_state(Inactive), _inc_bytes_used_before(0), @@ -70,23 +71,29 @@ } G1CollectionSet::~G1CollectionSet() { + if (_collection_set_regions != NULL) { + FREE_C_HEAP_ARRAY(uint, _collection_set_regions); + } delete _cset_chooser; } void G1CollectionSet::init_region_lengths(uint eden_cset_region_length, uint survivor_cset_region_length) { + assert_at_safepoint(true); + _eden_region_length = eden_cset_region_length; _survivor_region_length = survivor_cset_region_length; - assert((size_t) young_region_length() == _collection_set_regions.length(), - "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_regions.length()); + assert((size_t) young_region_length() == _collection_set_cur_length, + "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_cur_length); _old_region_length = 0; } void G1CollectionSet::set_max_length(uint max_region_length) { - guarantee(_collection_set_regions.max_length() == 0, "Must only initialize once."); - _collection_set_regions.initialize(max_region_length); + guarantee(_collection_set_regions == NULL, "Must only initialize once."); + _collection_set_max_length = max_region_length; + _collection_set_regions = NEW_C_HEAP_ARRAY(uint, max_region_length, mtGC); } void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) { @@ -95,13 +102,16 @@ // Add the heap region at the head of the non-incremental collection set void G1CollectionSet::add_old_region(HeapRegion* hr) { + assert_at_safepoint(true); + assert(_inc_build_state == Active, "Precondition"); assert(hr->is_old(), "the region should be old"); assert(!hr->in_collection_set(), "should not already be in the CSet"); _g1->register_old_region_with_cset(hr); - _collection_set_regions.par_push(hr->hrm_index()); + _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index(); + assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size."); _bytes_used_before += hr->used(); size_t rs_length = hr->rem_set()->occupied(); @@ -111,11 +121,9 @@ // Initialize the per-collection-set information void G1CollectionSet::start_incremental_building() { - assert(_collection_set_regions.length() == 0, "Must be empty before starting a new collection set."); + assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set."); assert(_inc_build_state == Inactive, "Precondition"); - _collection_set_regions.clear(); - _inc_bytes_used_before = 0; _inc_recorded_rs_lengths = 0; @@ -157,12 +165,18 @@ _inc_predicted_elapsed_time_ms_diffs = 0.0; } -void G1CollectionSet::iterate(HeapRegionClosure* cl) { - iterate_from(cl, 0, 1, true); +void G1CollectionSet::clear() { + assert_at_safepoint(true); + _collection_set_cur_length = 0; +} + +void G1CollectionSet::iterate(HeapRegionClosure* cl, bool may_be_aborted) { + iterate_from(cl, 0, 1, may_be_aborted); } void G1CollectionSet::iterate_from(HeapRegionClosure* cl, uint worker_id, uint total_workers, bool may_be_aborted) { - size_t len = _collection_set_regions.length(); + size_t len = _collection_set_cur_length; + OrderAccess::loadload(); if (len == 0) { return; } @@ -170,10 +184,11 @@ size_t cur_pos = start_pos; do { - HeapRegion* r = G1CollectedHeap::heap()->region_at(_collection_set_regions.get_by_index(cur_pos)); + HeapRegion* r = G1CollectedHeap::heap()->region_at(_collection_set_regions[cur_pos]); bool result = cl->doHeapRegion(r); guarantee(may_be_aborted || !result, "This iteration should not abort."); if (result) { + cl->incomplete(); return; } cur_pos++; @@ -215,10 +230,16 @@ assert(hr->is_young(), "invariant"); assert(_inc_build_state == Active, "Precondition"); - size_t collection_set_length = _collection_set_regions.length(); + size_t collection_set_length = _collection_set_cur_length; assert(collection_set_length <= INT_MAX, "Collection set is too large with %d entries", (int)collection_set_length); hr->set_young_index_in_cset((int)collection_set_length); - _collection_set_regions.par_push(hr->hrm_index()); + + _collection_set_regions[_collection_set_cur_length] = hr->hrm_index(); + // Concurrent readers must observe the store of the value in the array before an + // update to the length field. + OrderAccess::storestore(); + _collection_set_cur_length++; + assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set larger than maximum allowed."); // This routine is used when: // * adding survivor regions to the incremental cset at the end of an @@ -266,11 +287,13 @@ #ifndef PRODUCT bool G1CollectionSet::verify_young_ages() { + assert_at_safepoint(true); + bool ret = true; - size_t length = _collection_set_regions.length(); + size_t length = _collection_set_cur_length; for (size_t i = 0; i < length; i++) { - HeapRegion* curr = G1CollectedHeap::heap()->region_at(_collection_set_regions.get_by_index(i)); + HeapRegion* curr = G1CollectedHeap::heap()->region_at(_collection_set_regions[i]); guarantee(curr->is_young(), "Region must be young but is %s", curr->get_type_str()); @@ -466,15 +489,17 @@ #ifdef ASSERT void G1CollectionSet::verify_young_cset_indices() const { + assert_at_safepoint(true); + ResourceMark rm; uint* heap_region_indices = NEW_RESOURCE_ARRAY(uint, young_region_length()); for (uint i = 0; i < young_region_length(); ++i) { heap_region_indices[i] = (uint)-1; } - size_t length = _collection_set_regions.length(); + size_t length = _collection_set_cur_length; for (size_t i = 0; i < length; i++) { - HeapRegion* hr = G1CollectedHeap::heap()->region_at(_collection_set_regions.get_by_index(i)); + HeapRegion* hr = G1CollectedHeap::heap()->region_at(_collection_set_regions[i]); const int idx = hr->young_index_in_cset(); assert(idx > -1, "Young index must be set for all regions in the incremental collection set but is not for region %u.", hr->hrm_index());