--- old/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java 2014-08-28 11:39:07.694531184 +0200 +++ new/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java 2014-08-28 11:39:07.629529278 +0200 @@ -43,8 +43,8 @@ // Mirror class for G1CollectedHeap. public class G1CollectedHeap extends SharedHeap { - // HeapRegionSeq _seq; - static private long hrsFieldOffset; + // HeapRegionManager _hrm; + static private long hrmFieldOffset; // MemRegion _g1_reserved; static private long g1ReservedFieldOffset; // size_t _summary_bytes_used; @@ -67,7 +67,7 @@ static private synchronized void initialize(TypeDataBase db) { Type type = db.lookupType("G1CollectedHeap"); - hrsFieldOffset = type.getField("_hrs").getOffset(); + hrmFieldOffset = type.getField("_hrm").getOffset(); summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used"); g1mmField = type.getAddressField("_g1mm"); oldSetFieldOffset = type.getField("_old_set").getOffset(); @@ -75,7 +75,7 @@ } public long capacity() { - return hrs().capacity(); + return hrm().capacity(); } public long used() { @@ -83,13 +83,13 @@ } public long n_regions() { - return hrs().length(); + return hrm().length(); } - private HeapRegionSeq hrs() { - Address hrsAddr = addr.addOffsetTo(hrsFieldOffset); - return (HeapRegionSeq) VMObjectFactory.newObject(HeapRegionSeq.class, - hrsAddr); + private HeapRegionManager hrm() { + Address hrmAddr = addr.addOffsetTo(hrmFieldOffset); + return (HeapRegionManager) VMObjectFactory.newObject(HeapRegionManager.class, + hrmAddr); } public G1MonitoringSupport g1mm() { @@ -110,7 +110,7 @@ } private Iterator heapRegionIterator() { - return hrs().heapRegionIterator(); + return hrm().heapRegionIterator(); } public void heapRegionIterate(SpaceClosure scl) { --- old/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-08-28 11:39:08.064542034 +0200 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-08-28 11:39:07.994539981 +0200 @@ -34,8 +34,8 @@ #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1RemSet.hpp" #include "gc_implementation/g1/heapRegion.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionSet.inline.hpp" #include "gc_implementation/shared/vmGCOperations.hpp" #include "gc_implementation/shared/gcTimer.hpp" @@ -1408,7 +1408,7 @@ void set_bit_for_region(HeapRegion* hr) { assert(!hr->continuesHumongous(), "should have filtered those out"); - BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index(); + BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index(); if (!hr->startsHumongous()) { // Normal (non-humongous) case: just set the bit. _region_bm->par_at_put(index, true); @@ -1596,7 +1596,7 @@ if (_verbose) { gclog_or_tty->print_cr("Region %u: marked bytes mismatch: " "expected: " SIZE_FORMAT ", actual: " SIZE_FORMAT, - hr->hrs_index(), exp_marked_bytes, act_marked_bytes); + hr->hrm_index(), exp_marked_bytes, act_marked_bytes); } failures += 1; } @@ -1605,7 +1605,7 @@ // (which was just calculated) region bit maps. // We're not OK if the bit in the calculated expected region // bitmap is set and the bit in the actual region bitmap is not. - BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index(); + BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index(); bool expected = _exp_region_bm->at(index); bool actual = _region_bm->at(index); @@ -1613,7 +1613,7 @@ if (_verbose) { gclog_or_tty->print_cr("Region %u: region bitmap mismatch: " "expected: %s, actual: %s", - hr->hrs_index(), + hr->hrm_index(), BOOL_TO_STR(expected), BOOL_TO_STR(actual)); } failures += 1; @@ -1634,7 +1634,7 @@ if (_verbose) { gclog_or_tty->print_cr("Region %u: card bitmap mismatch at " SIZE_FORMAT ": " "expected: %s, actual: %s", - hr->hrs_index(), i, + hr->hrm_index(), i, BOOL_TO_STR(expected), BOOL_TO_STR(actual)); } failures += 1; @@ -3254,7 +3254,7 @@ assert(limit_idx <= end_idx, "or else use atomics"); // Aggregate the "stripe" in the count data associated with hr. - uint hrs_index = hr->hrs_index(); + uint hrm_index = hr->hrm_index(); size_t marked_bytes = 0; for (uint i = 0; i < _max_worker_id; i += 1) { @@ -3263,7 +3263,7 @@ // Fetch the marked_bytes in this region for task i and // add it to the running total for this region. - marked_bytes += marked_bytes_array[hrs_index]; + marked_bytes += marked_bytes_array[hrm_index]; // Now union the bitmaps[0,max_worker_id)[start_idx..limit_idx) // into the global card bitmap. --- old/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp 2014-08-28 11:39:08.475554087 +0200 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp 2014-08-28 11:39:08.408552122 +0200 @@ -86,7 +86,7 @@ HeapWord* start = mr.start(); HeapWord* end = mr.end(); size_t region_size_bytes = mr.byte_size(); - uint index = hr->hrs_index(); + uint index = hr->hrm_index(); assert(!hr->continuesHumongous(), "should not be HC region"); assert(hr == g1h->heap_region_containing(start), "sanity"); --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-08-28 11:39:08.858565318 +0200 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-08-28 11:39:08.778562972 +0200 @@ -528,9 +528,9 @@ // again to allocate from it. append_secondary_free_list(); - assert(_hrs.num_free_regions() > 0, "if the secondary_free_list was not " + assert(_hrm.num_free_regions() > 0, "if the secondary_free_list was not " "empty we should have moved at least one entry to the free_list"); - HeapRegion* res = _hrs.allocate_free_region(is_old); + HeapRegion* res = _hrm.allocate_free_region(is_old); if (G1ConcRegionFreeingVerbose) { gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " "allocated "HR_FORMAT" from secondary_free_list", @@ -571,7 +571,7 @@ } } - res = _hrs.allocate_free_region(is_old); + res = _hrm.allocate_free_region(is_old); if (res == NULL) { if (G1ConcRegionFreeingVerbose) { @@ -597,7 +597,7 @@ // always expand the heap by an amount aligned to the heap // region size, the free list should in theory not be empty. // In either case allocate_free_region() will check for NULL. - res = _hrs.allocate_free_region(is_old); + res = _hrm.allocate_free_region(is_old); } else { _expand_heap_after_alloc_failure = false; } @@ -609,7 +609,7 @@ G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first, uint num_regions, size_t word_size) { - assert(first != G1_NO_HRS_INDEX, "pre-condition"); + assert(first != G1_NO_HRM_INDEX, "pre-condition"); assert(isHumongous(word_size), "word_size should be humongous"); assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); @@ -747,7 +747,7 @@ verify_region_sets_optional(); - uint first = G1_NO_HRS_INDEX; + uint first = G1_NO_HRM_INDEX; uint obj_regions = (uint)(align_size_up_(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords); if (obj_regions == 1) { @@ -756,7 +756,7 @@ // later. HeapRegion* hr = new_region(word_size, true /* is_old */, false /* do_expand */); if (hr != NULL) { - first = hr->hrs_index(); + first = hr->hrm_index(); } } else { // We can't allocate humongous regions spanning more than one region while @@ -772,18 +772,18 @@ // Policy: Try only empty regions (i.e. already committed first). Maybe we // are lucky enough to find some. - first = _hrs.find_contiguous_only_empty(obj_regions); - if (first != G1_NO_HRS_INDEX) { - _hrs.allocate_free_regions_starting_at(first, obj_regions); + first = _hrm.find_contiguous_only_empty(obj_regions); + if (first != G1_NO_HRM_INDEX) { + _hrm.allocate_free_regions_starting_at(first, obj_regions); } } - if (first == G1_NO_HRS_INDEX) { + if (first == G1_NO_HRM_INDEX) { // Policy: We could not find enough regions for the humongous object in the // free list. Look through the heap to find a mix of free and uncommitted regions. // If so, try expansion. - first = _hrs.find_contiguous_empty_or_unavailable(obj_regions); - if (first != G1_NO_HRS_INDEX) { + first = _hrm.find_contiguous_empty_or_unavailable(obj_regions); + if (first != G1_NO_HRM_INDEX) { // We found something. Make sure these regions are committed, i.e. expand // the heap. Alternatively we could do a defragmentation GC. ergo_verbose1(ErgoHeapSizing, @@ -792,7 +792,7 @@ ergo_format_byte("allocation request"), word_size * HeapWordSize); - _hrs.expand_at(first, obj_regions); + _hrm.expand_at(first, obj_regions); g1_policy()->record_new_heap_size(num_regions()); #ifdef ASSERT @@ -802,14 +802,14 @@ assert(is_on_master_free_list(hr), "sanity"); } #endif - _hrs.allocate_free_regions_starting_at(first, obj_regions); + _hrm.allocate_free_regions_starting_at(first, obj_regions); } else { // Policy: Potentially trigger a defragmentation GC. } } HeapWord* result = NULL; - if (first != G1_NO_HRS_INDEX) { + if (first != G1_NO_HRM_INDEX) { result = humongous_obj_allocate_initialize_regions(first, obj_regions, word_size); assert(result != NULL, "it should always return a valid result"); @@ -1244,7 +1244,7 @@ : _hr_printer(hr_printer) { } }; -void G1CollectedHeap::print_hrs_post_compaction() { +void G1CollectedHeap::print_hrm_post_compaction() { PostCompactionPrinterClosure cl(hr_printer()); heap_region_iterate(&cl); } @@ -1413,7 +1413,7 @@ // that all the COMMIT / UNCOMMIT events are generated before // the end GC event. - print_hrs_post_compaction(); + print_hrm_post_compaction(); _hr_printer.end_gc(true /* full */, (size_t) total_collections()); } @@ -1486,7 +1486,7 @@ // Update the number of full collections that have been completed. increment_old_marking_cycles_completed(false /* concurrent */); - _hrs.verify_optional(); + _hrm.verify_optional(); verify_region_sets_optional(); verify_after_gc(); @@ -1730,7 +1730,7 @@ ergo_format_byte("allocation request"), word_size * HeapWordSize); if (expand(expand_bytes)) { - _hrs.verify_optional(); + _hrm.verify_optional(); verify_region_sets_optional(); return attempt_allocation_at_safepoint(word_size, false /* expect_null_mutator_alloc_region */); @@ -1758,7 +1758,7 @@ uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes); assert(regions_to_expand > 0, "Must expand by at least one region"); - uint expanded_by = _hrs.expand_by(regions_to_expand); + uint expanded_by = _hrm.expand_by(regions_to_expand); if (expanded_by > 0) { size_t actual_expand_bytes = expanded_by * HeapRegion::GrainBytes; @@ -1771,7 +1771,7 @@ // The expansion of the virtual storage space was unsuccessful. // Let's see if it was because we ran out of swap. if (G1ExitOnExpansionFailure && - _hrs.available() >= regions_to_expand) { + _hrm.available() >= regions_to_expand) { // We had head room... vm_exit_out_of_memory(aligned_expand_bytes, OOM_MMAP_ERROR, "G1 heap expansion"); } @@ -1786,7 +1786,7 @@ HeapRegion::GrainBytes); uint num_regions_to_remove = (uint)(shrink_bytes / HeapRegion::GrainBytes); - uint num_regions_removed = _hrs.shrink_by(num_regions_to_remove); + uint num_regions_removed = _hrm.shrink_by(num_regions_to_remove); size_t shrunk_bytes = num_regions_removed * HeapRegion::GrainBytes; ergo_verbose3(ErgoHeapSizing, @@ -1819,7 +1819,7 @@ shrink_helper(shrink_bytes); rebuild_region_sets(true /* free_list_only */); - _hrs.verify_optional(); + _hrm.verify_optional(); verify_region_sets_optional(); } @@ -2028,7 +2028,7 @@ CMBitMap::mark_distance(), mtGC); - _hrs.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage); + _hrm.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage); g1_barrier_set()->initialize(cardtable_storage); // Do later initialization work for concurrent refinement. _cg1r->init(card_counts_storage); @@ -2049,8 +2049,8 @@ _g1h = this; - _in_cset_fast_test.initialize(_hrs.reserved().start(), _hrs.reserved().end(), HeapRegion::GrainBytes); - _humongous_is_live.initialize(_hrs.reserved().start(), _hrs.reserved().end(), HeapRegion::GrainBytes); + _in_cset_fast_test.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes); + _humongous_is_live.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes); // Create the ConcurrentMark data structure and thread. // (Must do this late, so that "max_regions" is defined.) @@ -2111,7 +2111,7 @@ // Here we allocate the dummy HeapRegion that is required by the // G1AllocRegion class. - HeapRegion* dummy_region = _hrs.get_dummy_region(); + HeapRegion* dummy_region = _hrm.get_dummy_region(); // We'll re-use the same region whether the alloc region will // require BOT updates or not and, if it doesn't, then a non-young @@ -2228,14 +2228,14 @@ } size_t G1CollectedHeap::capacity() const { - return _hrs.length() * HeapRegion::GrainBytes; + return _hrm.length() * HeapRegion::GrainBytes; } void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) { assert(!hr->continuesHumongous(), "pre-condition"); hr->reset_gc_time_stamp(); if (hr->startsHumongous()) { - uint first_index = hr->hrs_index() + 1; + uint first_index = hr->hrm_index() + 1; uint last_index = hr->last_hc_index(); for (uint i = first_index; i < last_index; i += 1) { HeapRegion* chr = region_at(i); @@ -2533,7 +2533,7 @@ } bool G1CollectedHeap::is_in(const void* p) const { - if (_hrs.reserved().contains(p)) { + if (_hrm.reserved().contains(p)) { // Given that we know that p is in the reserved space, // heap_region_containing_raw() should successfully // return the containing region. @@ -2547,7 +2547,7 @@ #ifdef ASSERT bool G1CollectedHeap::is_in_exact(const void* p) const { bool contains = reserved_region().contains(p); - bool available = _hrs.is_available(addr_to_region((HeapWord*)p)); + bool available = _hrm.is_available(addr_to_region((HeapWord*)p)); if (contains && available) { return true; } else { @@ -2614,7 +2614,7 @@ } void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { - _hrs.iterate(cl); + _hrm.iterate(cl); } void @@ -2622,7 +2622,7 @@ uint worker_id, uint num_workers, jint claim_value) const { - _hrs.par_iterate(cl, worker_id, num_workers, claim_value); + _hrm.par_iterate(cl, worker_id, num_workers, claim_value); } class ResetClaimValuesClosure: public HeapRegionClosure { @@ -2842,9 +2842,9 @@ } HeapRegion* G1CollectedHeap::next_compaction_region(const HeapRegion* from) const { - HeapRegion* result = _hrs.next_region_in_heap(from); + HeapRegion* result = _hrm.next_region_in_heap(from); while (result != NULL && result->isHumongous()) { - result = _hrs.next_region_in_heap(result); + result = _hrm.next_region_in_heap(result); } return result; } @@ -2904,7 +2904,7 @@ } size_t G1CollectedHeap::max_capacity() const { - return _hrs.reserved().byte_size(); + return _hrm.reserved().byte_size(); } jlong G1CollectedHeap::millis_since_last_gc() { @@ -3433,9 +3433,9 @@ st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", capacity()/K, used_unlocked()/K); st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", - _hrs.reserved().start(), - _hrs.reserved().start() + _hrs.length() + HeapRegion::GrainWords, - _hrs.reserved().end()); + _hrm.reserved().start(), + _hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords, + _hrm.reserved().end()); st->cr(); st->print(" region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K); uint young_regions = _young_list->length(); @@ -3678,7 +3678,7 @@ } G1CollectedHeap* g1h = G1CollectedHeap::heap(); - uint region_idx = r->hrs_index(); + uint region_idx = r->hrm_index(); bool is_candidate = !g1h->humongous_region_is_always_live(region_idx); // Is_candidate already filters out humongous regions with some remembered set. // This will not lead to humongous object that we mistakenly keep alive because @@ -4200,7 +4200,7 @@ // output from the concurrent mark thread interfering with this // logging output either. - _hrs.verify_optional(); + _hrm.verify_optional(); verify_region_sets_optional(); TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats()); @@ -6019,7 +6019,7 @@ bool locked) { assert(!hr->isHumongous(), "this is only for non-humongous regions"); assert(!hr->is_empty(), "the region should not be empty"); - assert(_hrs.is_available(hr->hrs_index()), "region should be committed"); + assert(_hrm.is_available(hr->hrm_index()), "region should be committed"); assert(free_list != NULL, "pre-condition"); if (G1VerifyBitmaps) { @@ -6050,7 +6050,7 @@ hr->set_notHumongous(); free_region(hr, free_list, par); - uint i = hr->hrs_index() + 1; + uint i = hr->hrm_index() + 1; while (i < last_index) { HeapRegion* curr_hr = region_at(i); assert(curr_hr->continuesHumongous(), "invariant"); @@ -6074,7 +6074,7 @@ assert(list != NULL, "list can't be null"); if (!list->is_empty()) { MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); - _hrs.insert_list_into_free_list(list); + _hrm.insert_list_into_free_list(list); } } @@ -6443,7 +6443,7 @@ // While this cleanup is not strictly necessary to be done (or done instantly), // given that their occurrence is very low, this saves us this additional // complexity. - uint region_idx = r->hrs_index(); + uint region_idx = r->hrm_index(); if (g1h->humongous_is_live(region_idx) || g1h->humongous_region_is_always_live(region_idx)) { @@ -6682,22 +6682,22 @@ // this is that during a full GC string deduplication needs to know if // a collected region was young or old when the full GC was initiated. } - _hrs.remove_all_free_regions(); + _hrm.remove_all_free_regions(); } class RebuildRegionSetsClosure : public HeapRegionClosure { private: bool _free_list_only; HeapRegionSet* _old_set; - HeapRegionSeq* _hrs; + HeapRegionManager* _hrm; size_t _total_used; public: RebuildRegionSetsClosure(bool free_list_only, - HeapRegionSet* old_set, HeapRegionSeq* hrs) : + HeapRegionSet* old_set, HeapRegionManager* hrm) : _free_list_only(free_list_only), - _old_set(old_set), _hrs(hrs), _total_used(0) { - assert(_hrs->num_free_regions() == 0, "pre-condition"); + _old_set(old_set), _hrm(hrm), _total_used(0) { + assert(_hrm->num_free_regions() == 0, "pre-condition"); if (!free_list_only) { assert(_old_set->is_empty(), "pre-condition"); } @@ -6710,7 +6710,7 @@ if (r->is_empty()) { // Add free regions to the free list - _hrs->insert_into_free_list(r); + _hrm->insert_into_free_list(r); } else if (!_free_list_only) { assert(!r->is_young(), "we should not come across young regions"); @@ -6738,7 +6738,7 @@ _young_list->empty_list(); } - RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_hrs); + RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_hrm); heap_region_iterate(&cl); if (!free_list_only) { @@ -6928,7 +6928,7 @@ private: HeapRegionSet* _old_set; HeapRegionSet* _humongous_set; - HeapRegionSeq* _hrs; + HeapRegionManager* _hrm; public: HeapRegionSetCount _old_count; @@ -6937,8 +6937,8 @@ VerifyRegionListsClosure(HeapRegionSet* old_set, HeapRegionSet* humongous_set, - HeapRegionSeq* hrs) : - _old_set(old_set), _humongous_set(humongous_set), _hrs(hrs), + HeapRegionManager* hrm) : + _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm), _old_count(), _humongous_count(), _free_count(){ } bool doHeapRegion(HeapRegion* hr) { @@ -6949,19 +6949,19 @@ if (hr->is_young()) { // TODO } else if (hr->startsHumongous()) { - assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->hrs_index())); + assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->hrm_index())); _humongous_count.increment(1u, hr->capacity()); } else if (hr->is_empty()) { - assert(_hrs->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrs_index())); + assert(_hrm->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrm_index())); _free_count.increment(1u, hr->capacity()); } else { - assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrs_index())); + assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrm_index())); _old_count.increment(1u, hr->capacity()); } return false; } - void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionSeq* free_list) { + void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) { guarantee(old_set->length() == _old_count.length(), err_msg("Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length())); guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), err_msg("Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, old_set->total_capacity_bytes(), _old_count.capacity())); @@ -6980,7 +6980,7 @@ assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); // First, check the explicit lists. - _hrs.verify(); + _hrm.verify(); { // Given that a concurrent operation might be adding regions to // the secondary free list we have to take the lock before @@ -7011,9 +7011,9 @@ // Finally, make sure that the region accounting in the lists is // consistent with what we see in the heap. - VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_hrs); + VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_hrm); heap_region_iterate(&cl); - cl.verify_counts(&_old_set, &_humongous_set, &_hrs); + cl.verify_counts(&_old_set, &_humongous_set, &_hrm); } // Optimized nmethod scanning --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp 2014-08-28 11:39:09.379580597 +0200 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp 2014-08-28 11:39:09.306578456 +0200 @@ -33,7 +33,7 @@ #include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/g1YCTypes.hpp" -#include "gc_implementation/g1/heapRegionSeq.hpp" +#include "gc_implementation/g1/heapRegionManager.hpp" #include "gc_implementation/g1/heapRegionSet.hpp" #include "gc_implementation/shared/hSpaceCounters.hpp" #include "gc_implementation/shared/parGCAllocBuffer.hpp" @@ -291,7 +291,7 @@ G1RegionMappingChangedListener _listener; // The sequence of all heap regions in the heap. - HeapRegionSeq _hrs; + HeapRegionManager _hrm; // Alloc region used to satisfy mutator allocation requests. MutatorAllocRegion _mutator_alloc_region; @@ -429,7 +429,7 @@ // If the HR printer is active, dump the state of the regions in the // heap after a compaction. - void print_hrs_post_compaction(); + void print_hrm_post_compaction(); double verify(bool guard, const char* msg); void verify_before_gc(); @@ -715,7 +715,7 @@ // We register a region with the fast "in collection set" test. We // simply set to true the array slot corresponding to this region. void register_region_with_in_cset_fast_test(HeapRegion* r) { - _in_cset_fast_test.set_in_cset(r->hrs_index()); + _in_cset_fast_test.set_in_cset(r->hrm_index()); } // This is a fast test on whether a reference points into the @@ -1171,17 +1171,17 @@ // But G1CollectedHeap doesn't yet support this. virtual bool is_maximal_no_gc() const { - return _hrs.available() == 0; + return _hrm.available() == 0; } // The current number of regions in the heap. - uint num_regions() const { return _hrs.length(); } + uint num_regions() const { return _hrm.length(); } // The max number of regions in the heap. - uint max_regions() const { return _hrs.max_length(); } + uint max_regions() const { return _hrm.max_length(); } // The number of regions that are completely free. - uint num_free_regions() const { return _hrs.num_free_regions(); } + uint num_free_regions() const { return _hrm.num_free_regions(); } // The number of regions that are not completely free. uint num_used_regions() const { return num_regions() - num_free_regions(); } @@ -1233,7 +1233,7 @@ #ifdef ASSERT bool is_on_master_free_list(HeapRegion* hr) { - return _hrs.is_free(hr); + return _hrm.is_free(hr); } #endif // ASSERT @@ -1245,7 +1245,7 @@ } void append_secondary_free_list() { - _hrs.insert_list_into_free_list(&_secondary_free_list); + _hrm.insert_list_into_free_list(&_secondary_free_list); } void append_secondary_free_list_if_not_empty_with_lock() { @@ -1356,13 +1356,13 @@ // Return "TRUE" iff the given object address is in the reserved // region of g1. bool is_in_g1_reserved(const void* p) const { - return _hrs.reserved().contains(p); + return _hrm.reserved().contains(p); } // Returns a MemRegion that corresponds to the space that has been // reserved for the heap MemRegion g1_reserved() const { - return _hrs.reserved(); + return _hrm.reserved(); } virtual bool is_in_closed_subset(const void* p) const; --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp 2014-08-28 11:39:09.796592826 +0200 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp 2014-08-28 11:39:09.726590773 +0200 @@ -30,15 +30,15 @@ #include "gc_implementation/g1/g1AllocRegion.inline.hpp" #include "gc_implementation/g1/g1CollectorPolicy.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/g1/heapRegionSet.inline.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "utilities/taskqueue.hpp" // Inline functions for G1CollectedHeap // Return the region with the given index. It assumes the index is valid. -inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrs.at(index); } +inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at(index); } inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const { assert(is_in_reserved(addr), @@ -48,7 +48,7 @@ } inline HeapWord* G1CollectedHeap::bottom_addr_for_region(uint index) const { - return _hrs.reserved().start() + index * HeapRegion::GrainWords; + return _hrm.reserved().start() + index * HeapRegion::GrainWords; } template @@ -57,7 +57,7 @@ assert(is_in_g1_reserved((const void*) addr), err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")", p2i((void*)addr), p2i(g1_reserved().start()), p2i(g1_reserved().end()))); - return _hrs.addr_to_region((HeapWord*) addr); + return _hrm.addr_to_region((HeapWord*) addr); } template @@ -87,7 +87,7 @@ } inline bool G1CollectedHeap::obj_in_cs(oop obj) { - HeapRegion* r = _hrs.addr_to_region((HeapWord*) obj); + HeapRegion* r = _hrm.addr_to_region((HeapWord*) obj); return r != NULL && r->in_collection_set(); } --- old/src/share/vm/gc_implementation/g1/g1RemSet.cpp 2014-08-28 11:39:10.177603998 +0200 +++ new/src/share/vm/gc_implementation/g1/g1RemSet.cpp 2014-08-28 11:39:10.106601916 +0200 @@ -32,7 +32,7 @@ #include "gc_implementation/g1/g1GCPhaseTimes.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" #include "memory/iterator.hpp" #include "oops/oop.inline.hpp" --- old/src/share/vm/gc_implementation/g1/heapRegion.cpp 2014-08-28 11:39:10.591616139 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegion.cpp 2014-08-28 11:39:10.519614028 +0200 @@ -29,7 +29,7 @@ #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/heapRegion.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/shared/liveRange.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/iterator.hpp" @@ -344,11 +344,11 @@ return low; } -HeapRegion::HeapRegion(uint hrs_index, +HeapRegion::HeapRegion(uint hrm_index, G1BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) : G1OffsetTableContigSpace(sharedOffsetArray, mr), - _hrs_index(hrs_index), + _hrm_index(hrm_index), _humongous_type(NotHumongous), _humongous_start_region(NULL), _in_collection_set(false), _next_in_special_set(NULL), _orig_end(NULL), --- old/src/share/vm/gc_implementation/g1/heapRegion.hpp 2014-08-28 11:39:11.001628163 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegion.hpp 2014-08-28 11:39:10.926625963 +0200 @@ -54,15 +54,15 @@ #define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]" #define HR_FORMAT_PARAMS(_hr_) \ - (_hr_)->hrs_index(), \ + (_hr_)->hrm_index(), \ (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : \ (_hr_)->startsHumongous() ? "HS" : \ (_hr_)->continuesHumongous() ? "HC" : \ !(_hr_)->is_empty() ? "O" : "F", \ p2i((_hr_)->bottom()), p2i((_hr_)->top()), p2i((_hr_)->end()) -// sentinel value for hrs_index -#define G1_NO_HRS_INDEX ((uint) -1) +// sentinel value for hrm_index +#define G1_NO_HRM_INDEX ((uint) -1) // A dirty card to oop closure for heap regions. It // knows how to get the G1 heap and how to use the bitmap @@ -234,7 +234,7 @@ protected: // The index of this region in the heap region sequence. - uint _hrs_index; + uint _hrm_index; HumongousType _humongous_type; // For a humongous region, region in which it starts. @@ -330,7 +330,7 @@ size_t _predicted_bytes_to_copy; public: - HeapRegion(uint hrs_index, + HeapRegion(uint hrm_index, G1BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr); @@ -385,9 +385,9 @@ inline HeapWord* par_allocate_no_bot_updates(size_t word_size); inline HeapWord* allocate_no_bot_updates(size_t word_size); - // If this region is a member of a HeapRegionSeq, the index in that + // If this region is a member of a HeapRegionManager, the index in that // sequence, otherwise -1. - uint hrs_index() const { return _hrs_index; } + uint hrm_index() const { return _hrm_index; } // The number of bytes marked live in the region in the last marking phase. size_t marked_bytes() { return _prev_marked_bytes; } @@ -458,7 +458,7 @@ // with this HS region. uint last_hc_index() const { assert(startsHumongous(), "don't call this otherwise"); - return hrs_index() + region_num(); + return hrm_index() + region_num(); } // Same as Space::is_in_reserved, but will use the original size of the region. @@ -813,7 +813,7 @@ // HeapRegionClosure is used for iterating over regions. // Terminates the iteration when the "doHeapRegion" method returns "true". class HeapRegionClosure : public StackObj { - friend class HeapRegionSeq; + friend class HeapRegionManager; friend class G1CollectedHeap; bool _complete; --- old/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp 2014-08-28 11:39:11.416640332 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp 2014-08-28 11:39:11.342638162 +0200 @@ -27,7 +27,7 @@ #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "memory/allocation.hpp" #include "memory/padded.inline.hpp" #include "memory/space.inline.hpp" @@ -419,7 +419,7 @@ } void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) { - uint cur_hrs_ind = hr()->hrs_index(); + uint cur_hrm_ind = hr()->hrm_index(); if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").", @@ -434,10 +434,10 @@ if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = "INT32_FORMAT")", hr()->bottom(), from_card, - FromCardCache::at((uint)tid, cur_hrs_ind)); + FromCardCache::at((uint)tid, cur_hrm_ind)); } - if (FromCardCache::contains_or_replace((uint)tid, cur_hrs_ind, from_card)) { + if (FromCardCache::contains_or_replace((uint)tid, cur_hrm_ind, from_card)) { if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print_cr(" from-card cache hit."); } @@ -447,7 +447,7 @@ // Note that this may be a continued H region. HeapRegion* from_hr = _g1h->heap_region_containing_raw(from); - RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrs_index(); + RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrm_index(); // If the region is already coarsened, return. if (_coarse_map.at(from_hrs_ind)) { @@ -493,8 +493,8 @@ } else { if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print_cr(" [tid %d] sparse table entry " - "overflow(f: %d, t: %d)", - tid, from_hrs_ind, cur_hrs_ind); + "overflow(f: %d, t: %u)", + tid, from_hrs_ind, cur_hrm_ind); } } @@ -606,9 +606,9 @@ guarantee(max != NULL, "Since _n_fine_entries > 0"); // Set the corresponding coarse bit. - size_t max_hrs_index = (size_t) max->hr()->hrs_index(); - if (!_coarse_map.at(max_hrs_index)) { - _coarse_map.at_put(max_hrs_index, true); + size_t max_hrm_index = (size_t) max->hr()->hrm_index(); + if (!_coarse_map.at(max_hrm_index)) { + _coarse_map.at_put(max_hrm_index, true); _n_coarse_entries++; if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] " @@ -632,7 +632,7 @@ BitMap* region_bm, BitMap* card_bm) { // First eliminated garbage regions from the coarse map. if (G1RSScrubVerbose) { - gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrs_index()); + gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index()); } assert(_coarse_map.size() == region_bm->size(), "Precondition"); @@ -655,9 +655,9 @@ // If the entire region is dead, eliminate. if (G1RSScrubVerbose) { gclog_or_tty->print_cr(" For other region %u:", - cur->hr()->hrs_index()); + cur->hr()->hrm_index()); } - if (!region_bm->at((size_t) cur->hr()->hrs_index())) { + if (!region_bm->at((size_t) cur->hr()->hrm_index())) { *prev = nxt; cur->set_collision_list_next(NULL); _n_fine_entries--; @@ -751,7 +751,7 @@ } void OtherRegionsTable::clear_fcc() { - FromCardCache::clear(hr()->hrs_index()); + FromCardCache::clear(hr()->hrm_index()); } void OtherRegionsTable::clear() { @@ -802,7 +802,7 @@ bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const { HeapRegion* hr = _g1h->heap_region_containing_raw(from); - RegionIdx_t hr_ind = (RegionIdx_t) hr->hrs_index(); + RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index(); // Is this region in the coarse map? if (_coarse_map.at(hr_ind)) return true; @@ -839,7 +839,7 @@ HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr) : _bosa(bosa), - _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrs_index()), true), + _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true), _code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) { reset_for_par_iteration(); } --- old/src/share/vm/gc_implementation/g1/heapRegionSet.cpp 2014-08-28 11:39:11.828652414 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegionSet.cpp 2014-08-28 11:39:11.751650156 +0200 @@ -39,11 +39,11 @@ #ifndef PRODUCT void HeapRegionSetBase::verify_region(HeapRegion* hr) { - assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrs_index())); - assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrs_index())); // currently we don't use these sets for young regions - assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrs_index(), name())); - assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrs_index(), name())); - assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrs_index())); + assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrm_index())); + assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrm_index())); // currently we don't use these sets for young regions + assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrm_index(), name())); + assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrm_index(), name())); + assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrm_index())); } #endif @@ -158,7 +158,7 @@ HeapRegion* curr_from = from_list->_head; while (curr_from != NULL) { - while (curr_to != NULL && curr_to->hrs_index() < curr_from->hrs_index()) { + while (curr_to != NULL && curr_to->hrm_index() < curr_from->hrm_index()) { curr_to = curr_to->next(); } @@ -183,7 +183,7 @@ } } - if (_tail->hrs_index() < from_list->_tail->hrs_index()) { + if (_tail->hrm_index() < from_list->_tail->hrm_index()) { _tail = from_list->_tail; } } @@ -309,8 +309,8 @@ if (curr->next() != NULL) { guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up"); } - guarantee(curr->hrs_index() == 0 || curr->hrs_index() > last_index, "List should be sorted"); - last_index = curr->hrs_index(); + guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted"); + last_index = curr->hrm_index(); capacity += curr->capacity(); @@ -319,7 +319,7 @@ curr = curr->next(); } - guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrs_index(), prev0->hrs_index())); + guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index())); guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next"); guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count)); guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, --- old/src/share/vm/gc_implementation/g1/heapRegionSet.hpp 2014-08-28 11:39:12.246664672 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegionSet.hpp 2014-08-28 11:39:12.172662502 +0200 @@ -238,14 +238,14 @@ // Add hr to the list. The region should not be a member of another set. // Assumes that the list is ordered and will preserve that order. The order - // is determined by hrs_index. + // is determined by hrm_index. inline void add_ordered(HeapRegion* hr); // Removes from head or tail based on the given argument. HeapRegion* remove_region(bool from_head); // Merge two ordered lists. The result is also ordered. The order is - // determined by hrs_index. + // determined by hrm_index. void add_ordered(FreeRegionList* from_list); // It empties the list by removing all regions from it. --- old/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp 2014-08-28 11:39:12.661676842 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp 2014-08-28 11:39:12.586674643 +0200 @@ -60,14 +60,14 @@ if (_head != NULL) { HeapRegion* curr; - if (_last != NULL && _last->hrs_index() < hr->hrs_index()) { + if (_last != NULL && _last->hrm_index() < hr->hrm_index()) { curr = _last; } else { curr = _head; } // Find first entry with a Region Index larger than entry to insert. - while (curr != NULL && curr->hrs_index() < hr->hrs_index()) { + while (curr != NULL && curr->hrm_index() < hr->hrm_index()) { curr = curr->next(); } --- old/src/share/vm/gc_implementation/g1/sparsePRT.cpp 2014-08-28 11:39:13.062688602 +0200 +++ new/src/share/vm/gc_implementation/g1/sparsePRT.cpp 2014-08-28 11:39:12.993686578 +0200 @@ -478,7 +478,7 @@ bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) { #if SPARSE_PRT_VERBOSE gclog_or_tty->print_cr(" Adding card %d from region %d to region %u sparse.", - card_index, region_id, _hr->hrs_index()); + card_index, region_id, _hr->hrm_index()); #endif if (_next->occupied_entries() * 2 > _next->capacity()) { expand(); @@ -530,7 +530,7 @@ #if SPARSE_PRT_VERBOSE gclog_or_tty->print_cr(" Expanded sparse table for %u to %d.", - _hr->hrs_index(), _next->capacity()); + _hr->hrm_index(), _next->capacity()); #endif for (size_t i = 0; i < last->capacity(); i++) { SparsePRTEntry* e = last->entry((int)i); --- old/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp 2014-08-28 11:39:13.467700478 +0200 +++ new/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp 2014-08-28 11:39:13.390698220 +0200 @@ -26,7 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_G1_VMSTRUCTS_G1_HPP #include "gc_implementation/g1/heapRegion.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #define VM_STRUCTS_G1(nonstatic_field, static_field) \ @@ -42,10 +42,10 @@ nonstatic_field(G1HeapRegionTable, _bias, size_t) \ nonstatic_field(G1HeapRegionTable, _shift_by, uint) \ \ - nonstatic_field(HeapRegionSeq, _regions, G1HeapRegionTable) \ - nonstatic_field(HeapRegionSeq, _num_committed, uint) \ + nonstatic_field(HeapRegionManager, _regions, G1HeapRegionTable) \ + nonstatic_field(HeapRegionManager, _num_committed, uint) \ \ - nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \ + nonstatic_field(G1CollectedHeap, _hrm, HeapRegionManager) \ nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t) \ nonstatic_field(G1CollectedHeap, _g1mm, G1MonitoringSupport*) \ nonstatic_field(G1CollectedHeap, _old_set, HeapRegionSetBase) \ @@ -72,7 +72,7 @@ \ declare_type(G1OffsetTableContigSpace, CompactibleSpace) \ declare_type(HeapRegion, G1OffsetTableContigSpace) \ - declare_toplevel_type(HeapRegionSeq) \ + declare_toplevel_type(HeapRegionManager) \ declare_toplevel_type(HeapRegionSetBase) \ declare_toplevel_type(HeapRegionSetCount) \ declare_toplevel_type(G1MonitoringSupport) \ --- old/src/share/vm/oops/instanceKlass.cpp 2014-08-28 11:39:13.863712091 +0200 +++ new/src/share/vm/oops/instanceKlass.cpp 2014-08-28 11:39:13.791709980 +0200 @@ -66,7 +66,7 @@ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" --- old/src/share/vm/oops/instanceMirrorKlass.cpp 2014-08-28 11:39:14.291724642 +0200 +++ new/src/share/vm/oops/instanceMirrorKlass.cpp 2014-08-28 11:39:14.217722472 +0200 @@ -42,7 +42,7 @@ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" --- old/src/share/vm/oops/instanceRefKlass.cpp 2014-08-28 11:39:14.680736050 +0200 +++ new/src/share/vm/oops/instanceRefKlass.cpp 2014-08-28 11:39:14.611734026 +0200 @@ -38,7 +38,7 @@ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" --- old/src/share/vm/oops/objArrayKlass.cpp 2014-08-28 11:39:15.101748396 +0200 +++ new/src/share/vm/oops/objArrayKlass.cpp 2014-08-28 11:39:15.026746196 +0200 @@ -51,7 +51,7 @@ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parallelScavenge/psCompactionManager.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" --- old/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java 2014-08-28 11:39:15.521760712 +0200 +++ /dev/null 2014-08-11 17:55:13.749734341 +0200 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.gc_implementation.g1; - -import java.util.Iterator; -import java.util.Observable; -import java.util.Observer; - -import sun.jvm.hotspot.debugger.Address; -import sun.jvm.hotspot.runtime.VM; -import sun.jvm.hotspot.runtime.VMObject; -import sun.jvm.hotspot.runtime.VMObjectFactory; -import sun.jvm.hotspot.types.AddressField; -import sun.jvm.hotspot.types.CIntegerField; -import sun.jvm.hotspot.types.Type; -import sun.jvm.hotspot.types.TypeDataBase; - -// Mirror class for HeapRegionSeq. It essentially encapsulates the G1HeapRegionTable. - -public class HeapRegionSeq extends VMObject { - // G1HeapRegionTable _regions - static private long regionsFieldOffset; - // uint _committed_length - static private CIntegerField numCommittedField; - - static { - VM.registerVMInitializedObserver(new Observer() { - public void update(Observable o, Object data) { - initialize(VM.getVM().getTypeDataBase()); - } - }); - } - - static private synchronized void initialize(TypeDataBase db) { - Type type = db.lookupType("HeapRegionSeq"); - - regionsFieldOffset = type.getField("_regions").getOffset(); - numCommittedField = type.getCIntegerField("_num_committed"); - } - - private G1HeapRegionTable regions() { - Address regionsAddr = addr.addOffsetTo(regionsFieldOffset); - return (G1HeapRegionTable) VMObjectFactory.newObject(G1HeapRegionTable.class, - regionsAddr); - } - - public long capacity() { - return length() * HeapRegion.grainBytes(); - } - - public long length() { - return regions().length(); - } - - public long committedLength() { - return numCommittedField.getValue(addr); - } - - public Iterator heapRegionIterator() { - return regions().heapRegionIterator(length()); - } - - public HeapRegionSeq(Address addr) { - super(addr); - } -} --- /dev/null 2014-08-11 17:55:13.749734341 +0200 +++ new/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionManager.java 2014-08-28 11:39:15.446758513 +0200 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.gc_implementation.g1; + +import java.util.Iterator; +import java.util.Observable; +import java.util.Observer; + +import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.runtime.VM; +import sun.jvm.hotspot.runtime.VMObject; +import sun.jvm.hotspot.runtime.VMObjectFactory; +import sun.jvm.hotspot.types.AddressField; +import sun.jvm.hotspot.types.CIntegerField; +import sun.jvm.hotspot.types.Type; +import sun.jvm.hotspot.types.TypeDataBase; + +// Mirror class for HeapRegionManager. + +public class HeapRegionManager extends VMObject { + // G1HeapRegionTable _regions + static private long regionsFieldOffset; + // uint _committed_length + static private CIntegerField numCommittedField; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + static private synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("HeapRegionManager"); + + regionsFieldOffset = type.getField("_regions").getOffset(); + numCommittedField = type.getCIntegerField("_num_committed"); + } + + private G1HeapRegionTable regions() { + Address regionsAddr = addr.addOffsetTo(regionsFieldOffset); + return (G1HeapRegionTable) VMObjectFactory.newObject(G1HeapRegionTable.class, + regionsAddr); + } + + public long capacity() { + return length() * HeapRegion.grainBytes(); + } + + public long length() { + return regions().length(); + } + + public long committedLength() { + return numCommittedField.getValue(addr); + } + + public Iterator heapRegionIterator() { + return regions().heapRegionIterator(length()); + } + + public HeapRegionManager(Address addr) { + super(addr); + } +} --- old/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp 2014-08-28 11:39:15.948773234 +0200 +++ /dev/null 2014-08-11 17:55:13.749734341 +0200 @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc_implementation/g1/heapRegion.hpp" -#include "gc_implementation/g1/heapRegionSeq.inline.hpp" -#include "gc_implementation/g1/heapRegionSet.inline.hpp" -#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" -#include "gc_implementation/g1/concurrentG1Refine.hpp" -#include "memory/allocation.hpp" - -void HeapRegionSeq::initialize(G1RegionToSpaceMapper* heap_storage, - G1RegionToSpaceMapper* prev_bitmap, - G1RegionToSpaceMapper* next_bitmap, - G1RegionToSpaceMapper* bot, - G1RegionToSpaceMapper* cardtable, - G1RegionToSpaceMapper* card_counts) { - _allocated_heapregions_length = 0; - - _heap_mapper = heap_storage; - - _prev_bitmap_mapper = prev_bitmap; - _next_bitmap_mapper = next_bitmap; - - _bot_mapper = bot; - _cardtable_mapper = cardtable; - - _card_counts_mapper = card_counts; - - MemRegion reserved = heap_storage->reserved(); - _regions.initialize(reserved.start(), reserved.end(), HeapRegion::GrainBytes); - - _available_map.resize(_regions.length(), false); - _available_map.clear(); -} - -bool HeapRegionSeq::is_available(uint region) const { - return _available_map.at(region); -} - -#ifdef ASSERT -bool HeapRegionSeq::is_free(HeapRegion* hr) const { - return _free_list.contains(hr); -} -#endif - -HeapRegion* HeapRegionSeq::new_heap_region(uint hrs_index) { - HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(hrs_index); - MemRegion mr(bottom, bottom + HeapRegion::GrainWords); - assert(reserved().contains(mr), "invariant"); - return new HeapRegion(hrs_index, G1CollectedHeap::heap()->bot_shared(), mr); -} - -void HeapRegionSeq::commit_regions(uint index, size_t num_regions) { - guarantee(num_regions > 0, "Must commit more than zero regions"); - guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions"); - - _num_committed += (uint)num_regions; - - _heap_mapper->commit_regions(index, num_regions); - - // Also commit auxiliary data - _prev_bitmap_mapper->commit_regions(index, num_regions); - _next_bitmap_mapper->commit_regions(index, num_regions); - - _bot_mapper->commit_regions(index, num_regions); - _cardtable_mapper->commit_regions(index, num_regions); - - _card_counts_mapper->commit_regions(index, num_regions); -} - -void HeapRegionSeq::uncommit_regions(uint start, size_t num_regions) { - guarantee(num_regions >= 1, err_msg("Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start)); - guarantee(_num_committed >= num_regions, "pre-condition"); - - // Print before uncommitting. - if (G1CollectedHeap::heap()->hr_printer()->is_active()) { - for (uint i = start; i < start + num_regions; i++) { - HeapRegion* hr = at(i); - G1CollectedHeap::heap()->hr_printer()->uncommit(hr->bottom(), hr->end()); - } - } - - _num_committed -= (uint)num_regions; - - _available_map.par_clear_range(start, start + num_regions, BitMap::unknown_range); - _heap_mapper->uncommit_regions(start, num_regions); - - // Also uncommit auxiliary data - _prev_bitmap_mapper->uncommit_regions(start, num_regions); - _next_bitmap_mapper->uncommit_regions(start, num_regions); - - _bot_mapper->uncommit_regions(start, num_regions); - _cardtable_mapper->uncommit_regions(start, num_regions); - - _card_counts_mapper->uncommit_regions(start, num_regions); -} - -void HeapRegionSeq::make_regions_available(uint start, uint num_regions) { - guarantee(num_regions > 0, "No point in calling this for zero regions"); - commit_regions(start, num_regions); - for (uint i = start; i < start + num_regions; i++) { - if (_regions.get_by_index(i) == NULL) { - HeapRegion* new_hr = new_heap_region(i); - _regions.set_by_index(i, new_hr); - _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1); - } - } - - _available_map.par_set_range(start, start + num_regions, BitMap::unknown_range); - - for (uint i = start; i < start + num_regions; i++) { - assert(is_available(i), err_msg("Just made region %u available but is apparently not.", i)); - HeapRegion* hr = at(i); - if (G1CollectedHeap::heap()->hr_printer()->is_active()) { - G1CollectedHeap::heap()->hr_printer()->commit(hr->bottom(), hr->end()); - } - HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i); - MemRegion mr(bottom, bottom + HeapRegion::GrainWords); - - hr->initialize(mr); - insert_into_free_list(at(i)); - } -} - -uint HeapRegionSeq::expand_by(uint num_regions) { - return expand_at(0, num_regions); -} - -uint HeapRegionSeq::expand_at(uint start, uint num_regions) { - if (num_regions == 0) { - return 0; - } - - uint cur = start; - uint idx_last_found = 0; - uint num_last_found = 0; - - uint expanded = 0; - - while (expanded < num_regions && - (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) { - uint to_expand = MIN2(num_regions - expanded, num_last_found); - make_regions_available(idx_last_found, to_expand); - expanded += to_expand; - cur = idx_last_found + num_last_found + 1; - } - - verify_optional(); - return expanded; -} - -uint HeapRegionSeq::find_contiguous(size_t num, bool empty_only) { - uint found = 0; - size_t length_found = 0; - uint cur = 0; - - while (length_found < num && cur < max_length()) { - HeapRegion* hr = _regions.get_by_index(cur); - if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) { - // This region is a potential candidate for allocation into. - length_found++; - } else { - // This region is not a candidate. The next region is the next possible one. - found = cur + 1; - length_found = 0; - } - cur++; - } - - if (length_found == num) { - for (uint i = found; i < (found + num); i++) { - HeapRegion* hr = _regions.get_by_index(i); - // sanity check - guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()), - err_msg("Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT - " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr))); - } - return found; - } else { - return G1_NO_HRS_INDEX; - } -} - -HeapRegion* HeapRegionSeq::next_region_in_heap(const HeapRegion* r) const { - guarantee(r != NULL, "Start region must be a valid region"); - guarantee(is_available(r->hrs_index()), err_msg("Trying to iterate starting from region %u which is not in the heap", r->hrs_index())); - for (uint i = r->hrs_index() + 1; i < _allocated_heapregions_length; i++) { - HeapRegion* hr = _regions.get_by_index(i); - if (is_available(i)) { - return hr; - } - } - return NULL; -} - -void HeapRegionSeq::iterate(HeapRegionClosure* blk) const { - uint len = max_length(); - - for (uint i = 0; i < len; i++) { - if (!is_available(i)) { - continue; - } - guarantee(at(i) != NULL, err_msg("Tried to access region %u that has a NULL HeapRegion*", i)); - bool res = blk->doHeapRegion(at(i)); - if (res) { - blk->incomplete(); - return; - } - } -} - -uint HeapRegionSeq::find_unavailable_from_idx(uint start_idx, uint* res_idx) const { - guarantee(res_idx != NULL, "checking"); - guarantee(start_idx <= (max_length() + 1), "checking"); - - uint num_regions = 0; - - uint cur = start_idx; - while (cur < max_length() && is_available(cur)) { - cur++; - } - if (cur == max_length()) { - return num_regions; - } - *res_idx = cur; - while (cur < max_length() && !is_available(cur)) { - cur++; - } - num_regions = cur - *res_idx; -#ifdef ASSERT - for (uint i = *res_idx; i < (*res_idx + num_regions); i++) { - assert(!is_available(i), "just checking"); - } - assert(cur == max_length() || num_regions == 0 || is_available(cur), - err_msg("The region at the current position %u must be available or at the end of the heap.", cur)); -#endif - return num_regions; -} - -uint HeapRegionSeq::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const { - return num_regions * worker_i / num_workers; -} - -void HeapRegionSeq::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const { - const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length); - - // Every worker will actually look at all regions, skipping over regions that - // are currently not committed. - // This also (potentially) iterates over regions newly allocated during GC. This - // is no problem except for some extra work. - for (uint count = 0; count < _allocated_heapregions_length; count++) { - const uint index = (start_index + count) % _allocated_heapregions_length; - assert(0 <= index && index < _allocated_heapregions_length, "sanity"); - // Skip over unavailable regions - if (!is_available(index)) { - continue; - } - HeapRegion* r = _regions.get_by_index(index); - // We'll ignore "continues humongous" regions (we'll process them - // when we come across their corresponding "start humongous" - // region) and regions already claimed. - if (r->claim_value() == claim_value || r->continuesHumongous()) { - continue; - } - // OK, try to claim it - if (!r->claimHeapRegion(claim_value)) { - continue; - } - // Success! - if (r->startsHumongous()) { - // If the region is "starts humongous" we'll iterate over its - // "continues humongous" first; in fact we'll do them - // first. The order is important. In one case, calling the - // closure on the "starts humongous" region might de-allocate - // and clear all its "continues humongous" regions and, as a - // result, we might end up processing them twice. So, we'll do - // them first (note: most closures will ignore them anyway) and - // then we'll do the "starts humongous" region. - for (uint ch_index = index + 1; ch_index < index + r->region_num(); ch_index++) { - HeapRegion* chr = _regions.get_by_index(ch_index); - - assert(chr->continuesHumongous(), "Must be humongous region"); - assert(chr->humongous_start_region() == r, - err_msg("Must work on humongous continuation of the original start region " - PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr))); - assert(chr->claim_value() != claim_value, - "Must not have been claimed yet because claiming of humongous continuation first claims the start region"); - - bool claim_result = chr->claimHeapRegion(claim_value); - // We should always be able to claim it; no one else should - // be trying to claim this region. - guarantee(claim_result, "We should always be able to claim the continuesHumongous part of the humongous object"); - - bool res2 = blk->doHeapRegion(chr); - if (res2) { - return; - } - - // Right now, this holds (i.e., no closure that actually - // does something with "continues humongous" regions - // clears them). We might have to weaken it in the future, - // but let's leave these two asserts here for extra safety. - assert(chr->continuesHumongous(), "should still be the case"); - assert(chr->humongous_start_region() == r, "sanity"); - } - } - - bool res = blk->doHeapRegion(r); - if (res) { - return; - } - } -} - -uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) { - assert(length() > 0, "the region sequence should not be empty"); - assert(length() <= _allocated_heapregions_length, "invariant"); - assert(_allocated_heapregions_length > 0, "we should have at least one region committed"); - assert(num_regions_to_remove < length(), "We should never remove all regions"); - - if (num_regions_to_remove == 0) { - return 0; - } - - uint removed = 0; - uint cur = _allocated_heapregions_length - 1; - uint idx_last_found = 0; - uint num_last_found = 0; - - while ((removed < num_regions_to_remove) && - (num_last_found = find_empty_from_idx_reverse(cur, &idx_last_found)) > 0) { - // Only allow uncommit from the end of the heap. - if ((idx_last_found + num_last_found) != _allocated_heapregions_length) { - return 0; - } - uint to_remove = MIN2(num_regions_to_remove - removed, num_last_found); - - uncommit_regions(idx_last_found + num_last_found - to_remove, to_remove); - - cur -= num_last_found; - removed += to_remove; - } - - verify_optional(); - - return removed; -} - -uint HeapRegionSeq::find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const { - guarantee(start_idx < _allocated_heapregions_length, "checking"); - guarantee(res_idx != NULL, "checking"); - - uint num_regions_found = 0; - - jlong cur = start_idx; - while (cur != -1 && !(is_available(cur) && at(cur)->is_empty())) { - cur--; - } - if (cur == -1) { - return num_regions_found; - } - jlong old_cur = cur; - // cur indexes the first empty region - while (cur != -1 && is_available(cur) && at(cur)->is_empty()) { - cur--; - } - *res_idx = cur + 1; - num_regions_found = old_cur - cur; - -#ifdef ASSERT - for (uint i = *res_idx; i < (*res_idx + num_regions_found); i++) { - assert(at(i)->is_empty(), "just checking"); - } -#endif - return num_regions_found; -} - -void HeapRegionSeq::verify() { - guarantee(length() <= _allocated_heapregions_length, - err_msg("invariant: _length: %u _allocated_length: %u", - length(), _allocated_heapregions_length)); - guarantee(_allocated_heapregions_length <= max_length(), - err_msg("invariant: _allocated_length: %u _max_length: %u", - _allocated_heapregions_length, max_length())); - - bool prev_committed = true; - uint num_committed = 0; - HeapWord* prev_end = heap_bottom(); - for (uint i = 0; i < _allocated_heapregions_length; i++) { - if (!is_available(i)) { - prev_committed = false; - continue; - } - num_committed++; - HeapRegion* hr = _regions.get_by_index(i); - guarantee(hr != NULL, err_msg("invariant: i: %u", i)); - guarantee(!prev_committed || hr->bottom() == prev_end, - err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, - i, HR_FORMAT_PARAMS(hr), p2i(prev_end))); - guarantee(hr->hrs_index() == i, - err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); - // Asserts will fire if i is >= _length - HeapWord* addr = hr->bottom(); - guarantee(addr_to_region(addr) == hr, "sanity"); - // We cannot check whether the region is part of a particular set: at the time - // this method may be called, we have only completed allocation of the regions, - // but not put into a region set. - prev_committed = true; - if (hr->startsHumongous()) { - prev_end = hr->orig_end(); - } else { - prev_end = hr->end(); - } - } - for (uint i = _allocated_heapregions_length; i < max_length(); i++) { - guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i)); - } - - guarantee(num_committed == _num_committed, err_msg("Found %u committed regions, but should be %u", num_committed, _num_committed)); - _free_list.verify(); -} - -#ifndef PRODUCT -void HeapRegionSeq::verify_optional() { - verify(); -} -#endif // PRODUCT - --- /dev/null 2014-08-11 17:55:13.749734341 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegionManager.cpp 2014-08-28 11:39:15.874771064 +0200 @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/g1/heapRegion.hpp" +#include "gc_implementation/g1/heapRegionManager.inline.hpp" +#include "gc_implementation/g1/heapRegionSet.inline.hpp" +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" +#include "gc_implementation/g1/concurrentG1Refine.hpp" +#include "memory/allocation.hpp" + +void HeapRegionManager::initialize(G1RegionToSpaceMapper* heap_storage, + G1RegionToSpaceMapper* prev_bitmap, + G1RegionToSpaceMapper* next_bitmap, + G1RegionToSpaceMapper* bot, + G1RegionToSpaceMapper* cardtable, + G1RegionToSpaceMapper* card_counts) { + _allocated_heapregions_length = 0; + + _heap_mapper = heap_storage; + + _prev_bitmap_mapper = prev_bitmap; + _next_bitmap_mapper = next_bitmap; + + _bot_mapper = bot; + _cardtable_mapper = cardtable; + + _card_counts_mapper = card_counts; + + MemRegion reserved = heap_storage->reserved(); + _regions.initialize(reserved.start(), reserved.end(), HeapRegion::GrainBytes); + + _available_map.resize(_regions.length(), false); + _available_map.clear(); +} + +bool HeapRegionManager::is_available(uint region) const { + return _available_map.at(region); +} + +#ifdef ASSERT +bool HeapRegionManager::is_free(HeapRegion* hr) const { + return _free_list.contains(hr); +} +#endif + +HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) { + HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(hrm_index); + MemRegion mr(bottom, bottom + HeapRegion::GrainWords); + assert(reserved().contains(mr), "invariant"); + return new HeapRegion(hrm_index, G1CollectedHeap::heap()->bot_shared(), mr); +} + +void HeapRegionManager::commit_regions(uint index, size_t num_regions) { + guarantee(num_regions > 0, "Must commit more than zero regions"); + guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions"); + + _num_committed += (uint)num_regions; + + _heap_mapper->commit_regions(index, num_regions); + + // Also commit auxiliary data + _prev_bitmap_mapper->commit_regions(index, num_regions); + _next_bitmap_mapper->commit_regions(index, num_regions); + + _bot_mapper->commit_regions(index, num_regions); + _cardtable_mapper->commit_regions(index, num_regions); + + _card_counts_mapper->commit_regions(index, num_regions); +} + +void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) { + guarantee(num_regions >= 1, err_msg("Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start)); + guarantee(_num_committed >= num_regions, "pre-condition"); + + // Print before uncommitting. + if (G1CollectedHeap::heap()->hr_printer()->is_active()) { + for (uint i = start; i < start + num_regions; i++) { + HeapRegion* hr = at(i); + G1CollectedHeap::heap()->hr_printer()->uncommit(hr->bottom(), hr->end()); + } + } + + _num_committed -= (uint)num_regions; + + _available_map.par_clear_range(start, start + num_regions, BitMap::unknown_range); + _heap_mapper->uncommit_regions(start, num_regions); + + // Also uncommit auxiliary data + _prev_bitmap_mapper->uncommit_regions(start, num_regions); + _next_bitmap_mapper->uncommit_regions(start, num_regions); + + _bot_mapper->uncommit_regions(start, num_regions); + _cardtable_mapper->uncommit_regions(start, num_regions); + + _card_counts_mapper->uncommit_regions(start, num_regions); +} + +void HeapRegionManager::make_regions_available(uint start, uint num_regions) { + guarantee(num_regions > 0, "No point in calling this for zero regions"); + commit_regions(start, num_regions); + for (uint i = start; i < start + num_regions; i++) { + if (_regions.get_by_index(i) == NULL) { + HeapRegion* new_hr = new_heap_region(i); + _regions.set_by_index(i, new_hr); + _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1); + } + } + + _available_map.par_set_range(start, start + num_regions, BitMap::unknown_range); + + for (uint i = start; i < start + num_regions; i++) { + assert(is_available(i), err_msg("Just made region %u available but is apparently not.", i)); + HeapRegion* hr = at(i); + if (G1CollectedHeap::heap()->hr_printer()->is_active()) { + G1CollectedHeap::heap()->hr_printer()->commit(hr->bottom(), hr->end()); + } + HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i); + MemRegion mr(bottom, bottom + HeapRegion::GrainWords); + + hr->initialize(mr); + insert_into_free_list(at(i)); + } +} + +uint HeapRegionManager::expand_by(uint num_regions) { + return expand_at(0, num_regions); +} + +uint HeapRegionManager::expand_at(uint start, uint num_regions) { + if (num_regions == 0) { + return 0; + } + + uint cur = start; + uint idx_last_found = 0; + uint num_last_found = 0; + + uint expanded = 0; + + while (expanded < num_regions && + (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) { + uint to_expand = MIN2(num_regions - expanded, num_last_found); + make_regions_available(idx_last_found, to_expand); + expanded += to_expand; + cur = idx_last_found + num_last_found + 1; + } + + verify_optional(); + return expanded; +} + +uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) { + uint found = 0; + size_t length_found = 0; + uint cur = 0; + + while (length_found < num && cur < max_length()) { + HeapRegion* hr = _regions.get_by_index(cur); + if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) { + // This region is a potential candidate for allocation into. + length_found++; + } else { + // This region is not a candidate. The next region is the next possible one. + found = cur + 1; + length_found = 0; + } + cur++; + } + + if (length_found == num) { + for (uint i = found; i < (found + num); i++) { + HeapRegion* hr = _regions.get_by_index(i); + // sanity check + guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()), + err_msg("Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT + " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr))); + } + return found; + } else { + return G1_NO_HRM_INDEX; + } +} + +HeapRegion* HeapRegionManager::next_region_in_heap(const HeapRegion* r) const { + guarantee(r != NULL, "Start region must be a valid region"); + guarantee(is_available(r->hrm_index()), err_msg("Trying to iterate starting from region %u which is not in the heap", r->hrm_index())); + for (uint i = r->hrm_index() + 1; i < _allocated_heapregions_length; i++) { + HeapRegion* hr = _regions.get_by_index(i); + if (is_available(i)) { + return hr; + } + } + return NULL; +} + +void HeapRegionManager::iterate(HeapRegionClosure* blk) const { + uint len = max_length(); + + for (uint i = 0; i < len; i++) { + if (!is_available(i)) { + continue; + } + guarantee(at(i) != NULL, err_msg("Tried to access region %u that has a NULL HeapRegion*", i)); + bool res = blk->doHeapRegion(at(i)); + if (res) { + blk->incomplete(); + return; + } + } +} + +uint HeapRegionManager::find_unavailable_from_idx(uint start_idx, uint* res_idx) const { + guarantee(res_idx != NULL, "checking"); + guarantee(start_idx <= (max_length() + 1), "checking"); + + uint num_regions = 0; + + uint cur = start_idx; + while (cur < max_length() && is_available(cur)) { + cur++; + } + if (cur == max_length()) { + return num_regions; + } + *res_idx = cur; + while (cur < max_length() && !is_available(cur)) { + cur++; + } + num_regions = cur - *res_idx; +#ifdef ASSERT + for (uint i = *res_idx; i < (*res_idx + num_regions); i++) { + assert(!is_available(i), "just checking"); + } + assert(cur == max_length() || num_regions == 0 || is_available(cur), + err_msg("The region at the current position %u must be available or at the end of the heap.", cur)); +#endif + return num_regions; +} + +uint HeapRegionManager::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const { + return num_regions * worker_i / num_workers; +} + +void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const { + const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length); + + // Every worker will actually look at all regions, skipping over regions that + // are currently not committed. + // This also (potentially) iterates over regions newly allocated during GC. This + // is no problem except for some extra work. + for (uint count = 0; count < _allocated_heapregions_length; count++) { + const uint index = (start_index + count) % _allocated_heapregions_length; + assert(0 <= index && index < _allocated_heapregions_length, "sanity"); + // Skip over unavailable regions + if (!is_available(index)) { + continue; + } + HeapRegion* r = _regions.get_by_index(index); + // We'll ignore "continues humongous" regions (we'll process them + // when we come across their corresponding "start humongous" + // region) and regions already claimed. + if (r->claim_value() == claim_value || r->continuesHumongous()) { + continue; + } + // OK, try to claim it + if (!r->claimHeapRegion(claim_value)) { + continue; + } + // Success! + if (r->startsHumongous()) { + // If the region is "starts humongous" we'll iterate over its + // "continues humongous" first; in fact we'll do them + // first. The order is important. In one case, calling the + // closure on the "starts humongous" region might de-allocate + // and clear all its "continues humongous" regions and, as a + // result, we might end up processing them twice. So, we'll do + // them first (note: most closures will ignore them anyway) and + // then we'll do the "starts humongous" region. + for (uint ch_index = index + 1; ch_index < index + r->region_num(); ch_index++) { + HeapRegion* chr = _regions.get_by_index(ch_index); + + assert(chr->continuesHumongous(), "Must be humongous region"); + assert(chr->humongous_start_region() == r, + err_msg("Must work on humongous continuation of the original start region " + PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr))); + assert(chr->claim_value() != claim_value, + "Must not have been claimed yet because claiming of humongous continuation first claims the start region"); + + bool claim_result = chr->claimHeapRegion(claim_value); + // We should always be able to claim it; no one else should + // be trying to claim this region. + guarantee(claim_result, "We should always be able to claim the continuesHumongous part of the humongous object"); + + bool res2 = blk->doHeapRegion(chr); + if (res2) { + return; + } + + // Right now, this holds (i.e., no closure that actually + // does something with "continues humongous" regions + // clears them). We might have to weaken it in the future, + // but let's leave these two asserts here for extra safety. + assert(chr->continuesHumongous(), "should still be the case"); + assert(chr->humongous_start_region() == r, "sanity"); + } + } + + bool res = blk->doHeapRegion(r); + if (res) { + return; + } + } +} + +uint HeapRegionManager::shrink_by(uint num_regions_to_remove) { + assert(length() > 0, "the region sequence should not be empty"); + assert(length() <= _allocated_heapregions_length, "invariant"); + assert(_allocated_heapregions_length > 0, "we should have at least one region committed"); + assert(num_regions_to_remove < length(), "We should never remove all regions"); + + if (num_regions_to_remove == 0) { + return 0; + } + + uint removed = 0; + uint cur = _allocated_heapregions_length - 1; + uint idx_last_found = 0; + uint num_last_found = 0; + + while ((removed < num_regions_to_remove) && + (num_last_found = find_empty_from_idx_reverse(cur, &idx_last_found)) > 0) { + // Only allow uncommit from the end of the heap. + if ((idx_last_found + num_last_found) != _allocated_heapregions_length) { + return 0; + } + uint to_remove = MIN2(num_regions_to_remove - removed, num_last_found); + + uncommit_regions(idx_last_found + num_last_found - to_remove, to_remove); + + cur -= num_last_found; + removed += to_remove; + } + + verify_optional(); + + return removed; +} + +uint HeapRegionManager::find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const { + guarantee(start_idx < _allocated_heapregions_length, "checking"); + guarantee(res_idx != NULL, "checking"); + + uint num_regions_found = 0; + + jlong cur = start_idx; + while (cur != -1 && !(is_available(cur) && at(cur)->is_empty())) { + cur--; + } + if (cur == -1) { + return num_regions_found; + } + jlong old_cur = cur; + // cur indexes the first empty region + while (cur != -1 && is_available(cur) && at(cur)->is_empty()) { + cur--; + } + *res_idx = cur + 1; + num_regions_found = old_cur - cur; + +#ifdef ASSERT + for (uint i = *res_idx; i < (*res_idx + num_regions_found); i++) { + assert(at(i)->is_empty(), "just checking"); + } +#endif + return num_regions_found; +} + +void HeapRegionManager::verify() { + guarantee(length() <= _allocated_heapregions_length, + err_msg("invariant: _length: %u _allocated_length: %u", + length(), _allocated_heapregions_length)); + guarantee(_allocated_heapregions_length <= max_length(), + err_msg("invariant: _allocated_length: %u _max_length: %u", + _allocated_heapregions_length, max_length())); + + bool prev_committed = true; + uint num_committed = 0; + HeapWord* prev_end = heap_bottom(); + for (uint i = 0; i < _allocated_heapregions_length; i++) { + if (!is_available(i)) { + prev_committed = false; + continue; + } + num_committed++; + HeapRegion* hr = _regions.get_by_index(i); + guarantee(hr != NULL, err_msg("invariant: i: %u", i)); + guarantee(!prev_committed || hr->bottom() == prev_end, + err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, + i, HR_FORMAT_PARAMS(hr), p2i(prev_end))); + guarantee(hr->hrm_index() == i, + err_msg("invariant: i: %u hrm_index(): %u", i, hr->hrm_index())); + // Asserts will fire if i is >= _length + HeapWord* addr = hr->bottom(); + guarantee(addr_to_region(addr) == hr, "sanity"); + // We cannot check whether the region is part of a particular set: at the time + // this method may be called, we have only completed allocation of the regions, + // but not put into a region set. + prev_committed = true; + if (hr->startsHumongous()) { + prev_end = hr->orig_end(); + } else { + prev_end = hr->end(); + } + } + for (uint i = _allocated_heapregions_length; i < max_length(); i++) { + guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i)); + } + + guarantee(num_committed == _num_committed, err_msg("Found %u committed regions, but should be %u", num_committed, _num_committed)); + _free_list.verify(); +} + +#ifndef PRODUCT +void HeapRegionManager::verify_optional() { + verify(); +} +#endif // PRODUCT + --- old/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp 2014-08-28 11:39:16.361785345 +0200 +++ /dev/null 2014-08-11 17:55:13.749734341 +0200 @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP -#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP - -#include "gc_implementation/g1/g1BiasedArray.hpp" -#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" -#include "gc_implementation/g1/heapRegionSet.hpp" - -class HeapRegion; -class HeapRegionClosure; -class FreeRegionList; - -class G1HeapRegionTable : public G1BiasedMappedArray { - protected: - virtual HeapRegion* default_value() const { return NULL; } -}; - -// This class keeps track of the actual heap memory, auxiliary data -// and its metadata (i.e., HeapRegion instances) and the list of free regions. -// -// This allows maximum flexibility for deciding what to commit or uncommit given -// a request from outside. -// -// HeapRegions are kept in the _regions array in address order. A region's -// index in the array corresponds to its index in the heap (i.e., 0 is the -// region at the bottom of the heap, 1 is the one after it, etc.). Two -// regions that are consecutive in the array should also be adjacent in the -// address space (i.e., region(i).end() == region(i+1).bottom(). -// -// We create a HeapRegion when we commit the region's address space -// for the first time. When we uncommit the address space of a -// region we retain the HeapRegion to be able to re-use it in the -// future (in case we recommit it). -// -// We keep track of three lengths: -// -// * _num_committed (returned by length()) is the number of currently -// committed regions. These may not be contiguous. -// * _allocated_heapregions_length (not exposed outside this class) is the -// number of regions+1 for which we have HeapRegions. -// * max_length() returns the maximum number of regions the heap can have. -// - -class HeapRegionSeq: public CHeapObj { - friend class VMStructs; - - G1HeapRegionTable _regions; - - G1RegionToSpaceMapper* _heap_mapper; - G1RegionToSpaceMapper* _prev_bitmap_mapper; - G1RegionToSpaceMapper* _next_bitmap_mapper; - G1RegionToSpaceMapper* _bot_mapper; - G1RegionToSpaceMapper* _cardtable_mapper; - G1RegionToSpaceMapper* _card_counts_mapper; - - FreeRegionList _free_list; - - // Each bit in this bitmap indicates that the corresponding region is available - // for allocation. - BitMap _available_map; - - // The number of regions committed in the heap. - uint _num_committed; - - // Internal only. The highest heap region +1 we allocated a HeapRegion instance for. - uint _allocated_heapregions_length; - - HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); } - HeapWord* heap_end() const {return _regions.end_address_mapped(); } - - void make_regions_available(uint index, uint num_regions = 1); - - // Pass down commit calls to the VirtualSpace. - void commit_regions(uint index, size_t num_regions = 1); - void uncommit_regions(uint index, size_t num_regions = 1); - - // Notify other data structures about change in the heap layout. - void update_committed_space(HeapWord* old_end, HeapWord* new_end); - // Calculate the starting region for each worker during parallel iteration so - // that they do not all start from the same region. - uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const; - - // Find a contiguous set of empty or uncommitted regions of length num and return - // the index of the first region or G1_NO_HRS_INDEX if the search was unsuccessful. - // If only_empty is true, only empty regions are considered. - // Searches from bottom to top of the heap, doing a first-fit. - uint find_contiguous(size_t num, bool only_empty); - // Finds the next sequence of unavailable regions starting from start_idx. Returns the - // length of the sequence found. If this result is zero, no such sequence could be found, - // otherwise res_idx indicates the start index of these regions. - uint find_unavailable_from_idx(uint start_idx, uint* res_idx) const; - // Finds the next sequence of empty regions starting from start_idx, going backwards in - // the heap. Returns the length of the sequence found. If this value is zero, no - // sequence could be found, otherwise res_idx contains the start index of this range. - uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const; - // Allocate a new HeapRegion for the given index. - HeapRegion* new_heap_region(uint hrs_index); -#ifdef ASSERT -public: - bool is_free(HeapRegion* hr) const; -#endif - // Returns whether the given region is available for allocation. - bool is_available(uint region) const; - - public: - // Empty constructor, we'll initialize it with the initialize() method. - HeapRegionSeq() : _regions(), _heap_mapper(NULL), _num_committed(0), - _next_bitmap_mapper(NULL), _prev_bitmap_mapper(NULL), _bot_mapper(NULL), - _allocated_heapregions_length(0), _available_map(), - _free_list("Free list", new MasterFreeRegionListMtSafeChecker()) - { } - - void initialize(G1RegionToSpaceMapper* heap_storage, - G1RegionToSpaceMapper* prev_bitmap, - G1RegionToSpaceMapper* next_bitmap, - G1RegionToSpaceMapper* bot, - G1RegionToSpaceMapper* cardtable, - G1RegionToSpaceMapper* card_counts); - - // Return the "dummy" region used for G1AllocRegion. This is currently a hardwired - // new HeapRegion that owns HeapRegion at index 0. Since at the moment we commit - // the heap from the lowest address, this region (and its associated data - // structures) are available and we do not need to check further. - HeapRegion* get_dummy_region() { return new_heap_region(0); } - - // Return the HeapRegion at the given index. Assume that the index - // is valid. - inline HeapRegion* at(uint index) const; - - // If addr is within the committed space return its corresponding - // HeapRegion, otherwise return NULL. - inline HeapRegion* addr_to_region(HeapWord* addr) const; - - // Insert the given region into the free region list. - inline void insert_into_free_list(HeapRegion* hr); - - // Insert the given region list into the global free region list. - void insert_list_into_free_list(FreeRegionList* list) { - _free_list.add_ordered(list); - } - - HeapRegion* allocate_free_region(bool is_old) { - HeapRegion* hr = _free_list.remove_region(is_old); - - if (hr != NULL) { - assert(hr->next() == NULL, "Single region should not have next"); - assert(is_available(hr->hrs_index()), "Must be committed"); - } - return hr; - } - - inline void allocate_free_regions_starting_at(uint first, uint num_regions); - - // Remove all regions from the free list. - void remove_all_free_regions() { - _free_list.remove_all(); - } - - // Return the number of committed free regions in the heap. - uint num_free_regions() const { - return _free_list.length(); - } - - size_t total_capacity_bytes() const { - return num_free_regions() * HeapRegion::GrainBytes; - } - - // Return the number of available (uncommitted) regions. - uint available() const { return max_length() - length(); } - - // Return the number of regions that have been committed in the heap. - uint length() const { return _num_committed; } - - // Return the maximum number of regions in the heap. - uint max_length() const { return (uint)_regions.length(); } - - MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); } - - // Expand the sequence to reflect that the heap has grown. Either create new - // HeapRegions, or re-use existing ones. Returns the number of regions the - // sequence was expanded by. If a HeapRegion allocation fails, the resulting - // number of regions might be smaller than what's desired. - uint expand_by(uint num_regions); - - // Makes sure that the regions from start to start+num_regions-1 are available - // for allocation. Returns the number of regions that were committed to achieve - // this. - uint expand_at(uint start, uint num_regions); - - // Find a contiguous set of empty regions of length num. Returns the start index of - // that set, or G1_NO_HRS_INDEX. - uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); } - // Find a contiguous set of empty or unavailable regions of length num. Returns the - // start index of that set, or G1_NO_HRS_INDEX. - uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); } - - HeapRegion* next_region_in_heap(const HeapRegion* r) const; - - // Apply blk->doHeapRegion() on all committed regions in address order, - // terminating the iteration early if doHeapRegion() returns true. - void iterate(HeapRegionClosure* blk) const; - - void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const; - - // Uncommit up to num_regions_to_remove regions that are completely free. - // Return the actual number of uncommitted regions. - uint shrink_by(uint num_regions_to_remove); - - void verify(); - - // Do some sanity checking. - void verify_optional() PRODUCT_RETURN; -}; - -#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP --- /dev/null 2014-08-11 17:55:13.749734341 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegionManager.hpp 2014-08-28 11:39:16.284783087 +0200 @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP +#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP + +#include "gc_implementation/g1/g1BiasedArray.hpp" +#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" +#include "gc_implementation/g1/heapRegionSet.hpp" + +class HeapRegion; +class HeapRegionClosure; +class FreeRegionList; + +class G1HeapRegionTable : public G1BiasedMappedArray { + protected: + virtual HeapRegion* default_value() const { return NULL; } +}; + +// This class keeps track of the actual heap memory, auxiliary data +// and its metadata (i.e., HeapRegion instances) and the list of free regions. +// +// This allows maximum flexibility for deciding what to commit or uncommit given +// a request from outside. +// +// HeapRegions are kept in the _regions array in address order. A region's +// index in the array corresponds to its index in the heap (i.e., 0 is the +// region at the bottom of the heap, 1 is the one after it, etc.). Two +// regions that are consecutive in the array should also be adjacent in the +// address space (i.e., region(i).end() == region(i+1).bottom(). +// +// We create a HeapRegion when we commit the region's address space +// for the first time. When we uncommit the address space of a +// region we retain the HeapRegion to be able to re-use it in the +// future (in case we recommit it). +// +// We keep track of three lengths: +// +// * _num_committed (returned by length()) is the number of currently +// committed regions. These may not be contiguous. +// * _allocated_heapregions_length (not exposed outside this class) is the +// number of regions+1 for which we have HeapRegions. +// * max_length() returns the maximum number of regions the heap can have. +// + +class HeapRegionManager: public CHeapObj { + friend class VMStructs; + + G1HeapRegionTable _regions; + + G1RegionToSpaceMapper* _heap_mapper; + G1RegionToSpaceMapper* _prev_bitmap_mapper; + G1RegionToSpaceMapper* _next_bitmap_mapper; + G1RegionToSpaceMapper* _bot_mapper; + G1RegionToSpaceMapper* _cardtable_mapper; + G1RegionToSpaceMapper* _card_counts_mapper; + + FreeRegionList _free_list; + + // Each bit in this bitmap indicates that the corresponding region is available + // for allocation. + BitMap _available_map; + + // The number of regions committed in the heap. + uint _num_committed; + + // Internal only. The highest heap region +1 we allocated a HeapRegion instance for. + uint _allocated_heapregions_length; + + HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); } + HeapWord* heap_end() const {return _regions.end_address_mapped(); } + + void make_regions_available(uint index, uint num_regions = 1); + + // Pass down commit calls to the VirtualSpace. + void commit_regions(uint index, size_t num_regions = 1); + void uncommit_regions(uint index, size_t num_regions = 1); + + // Notify other data structures about change in the heap layout. + void update_committed_space(HeapWord* old_end, HeapWord* new_end); + // Calculate the starting region for each worker during parallel iteration so + // that they do not all start from the same region. + uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const; + + // Find a contiguous set of empty or uncommitted regions of length num and return + // the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful. + // If only_empty is true, only empty regions are considered. + // Searches from bottom to top of the heap, doing a first-fit. + uint find_contiguous(size_t num, bool only_empty); + // Finds the next sequence of unavailable regions starting from start_idx. Returns the + // length of the sequence found. If this result is zero, no such sequence could be found, + // otherwise res_idx indicates the start index of these regions. + uint find_unavailable_from_idx(uint start_idx, uint* res_idx) const; + // Finds the next sequence of empty regions starting from start_idx, going backwards in + // the heap. Returns the length of the sequence found. If this value is zero, no + // sequence could be found, otherwise res_idx contains the start index of this range. + uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const; + // Allocate a new HeapRegion for the given index. + HeapRegion* new_heap_region(uint hrm_index); +#ifdef ASSERT +public: + bool is_free(HeapRegion* hr) const; +#endif + // Returns whether the given region is available for allocation. + bool is_available(uint region) const; + + public: + // Empty constructor, we'll initialize it with the initialize() method. + HeapRegionManager() : _regions(), _heap_mapper(NULL), _num_committed(0), + _next_bitmap_mapper(NULL), _prev_bitmap_mapper(NULL), _bot_mapper(NULL), + _allocated_heapregions_length(0), _available_map(), + _free_list("Free list", new MasterFreeRegionListMtSafeChecker()) + { } + + void initialize(G1RegionToSpaceMapper* heap_storage, + G1RegionToSpaceMapper* prev_bitmap, + G1RegionToSpaceMapper* next_bitmap, + G1RegionToSpaceMapper* bot, + G1RegionToSpaceMapper* cardtable, + G1RegionToSpaceMapper* card_counts); + + // Return the "dummy" region used for G1AllocRegion. This is currently a hardwired + // new HeapRegion that owns HeapRegion at index 0. Since at the moment we commit + // the heap from the lowest address, this region (and its associated data + // structures) are available and we do not need to check further. + HeapRegion* get_dummy_region() { return new_heap_region(0); } + + // Return the HeapRegion at the given index. Assume that the index + // is valid. + inline HeapRegion* at(uint index) const; + + // If addr is within the committed space return its corresponding + // HeapRegion, otherwise return NULL. + inline HeapRegion* addr_to_region(HeapWord* addr) const; + + // Insert the given region into the free region list. + inline void insert_into_free_list(HeapRegion* hr); + + // Insert the given region list into the global free region list. + void insert_list_into_free_list(FreeRegionList* list) { + _free_list.add_ordered(list); + } + + HeapRegion* allocate_free_region(bool is_old) { + HeapRegion* hr = _free_list.remove_region(is_old); + + if (hr != NULL) { + assert(hr->next() == NULL, "Single region should not have next"); + assert(is_available(hr->hrm_index()), "Must be committed"); + } + return hr; + } + + inline void allocate_free_regions_starting_at(uint first, uint num_regions); + + // Remove all regions from the free list. + void remove_all_free_regions() { + _free_list.remove_all(); + } + + // Return the number of committed free regions in the heap. + uint num_free_regions() const { + return _free_list.length(); + } + + size_t total_capacity_bytes() const { + return num_free_regions() * HeapRegion::GrainBytes; + } + + // Return the number of available (uncommitted) regions. + uint available() const { return max_length() - length(); } + + // Return the number of regions that have been committed in the heap. + uint length() const { return _num_committed; } + + // Return the maximum number of regions in the heap. + uint max_length() const { return (uint)_regions.length(); } + + MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); } + + // Expand the sequence to reflect that the heap has grown. Either create new + // HeapRegions, or re-use existing ones. Returns the number of regions the + // sequence was expanded by. If a HeapRegion allocation fails, the resulting + // number of regions might be smaller than what's desired. + uint expand_by(uint num_regions); + + // Makes sure that the regions from start to start+num_regions-1 are available + // for allocation. Returns the number of regions that were committed to achieve + // this. + uint expand_at(uint start, uint num_regions); + + // Find a contiguous set of empty regions of length num. Returns the start index of + // that set, or G1_NO_HRM_INDEX. + uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); } + // Find a contiguous set of empty or unavailable regions of length num. Returns the + // start index of that set, or G1_NO_HRM_INDEX. + uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); } + + HeapRegion* next_region_in_heap(const HeapRegion* r) const; + + // Apply blk->doHeapRegion() on all committed regions in address order, + // terminating the iteration early if doHeapRegion() returns true. + void iterate(HeapRegionClosure* blk) const; + + void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const; + + // Uncommit up to num_regions_to_remove regions that are completely free. + // Return the actual number of uncommitted regions. + uint shrink_by(uint num_regions_to_remove); + + void verify(); + + // Do some sanity checking. + void verify_optional() PRODUCT_RETURN; +}; + +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP --- old/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp 2014-08-28 11:39:16.794798043 +0200 +++ /dev/null 2014-08-11 17:55:13.749734341 +0200 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP -#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP - -#include "gc_implementation/g1/heapRegion.hpp" -#include "gc_implementation/g1/heapRegionSeq.hpp" -#include "gc_implementation/g1/heapRegionSet.inline.hpp" - -inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { - assert(addr < heap_end(), - err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end()))); - assert(addr >= heap_bottom(), - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, p2i(addr), p2i(heap_bottom()))); - - HeapRegion* hr = _regions.get_by_address(addr); - return hr; -} - -inline HeapRegion* HeapRegionSeq::at(uint index) const { - assert(is_available(index), "pre-condition"); - HeapRegion* hr = _regions.get_by_index(index); - assert(hr != NULL, "sanity"); - assert(hr->hrs_index() == index, "sanity"); - return hr; -} - -inline void HeapRegionSeq::insert_into_free_list(HeapRegion* hr) { - _free_list.add_ordered(hr); -} - -inline void HeapRegionSeq::allocate_free_regions_starting_at(uint first, uint num_regions) { - _free_list.remove_starting_at(at(first), num_regions); -} - -#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP --- /dev/null 2014-08-11 17:55:13.749734341 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp 2014-08-28 11:39:16.718795814 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP +#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP + +#include "gc_implementation/g1/heapRegion.hpp" +#include "gc_implementation/g1/heapRegionManager.hpp" +#include "gc_implementation/g1/heapRegionSet.inline.hpp" + +inline HeapRegion* HeapRegionManager::addr_to_region(HeapWord* addr) const { + assert(addr < heap_end(), + err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end()))); + assert(addr >= heap_bottom(), + err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, p2i(addr), p2i(heap_bottom()))); + + HeapRegion* hr = _regions.get_by_address(addr); + return hr; +} + +inline HeapRegion* HeapRegionManager::at(uint index) const { + assert(is_available(index), "pre-condition"); + HeapRegion* hr = _regions.get_by_index(index); + assert(hr != NULL, "sanity"); + assert(hr->hrm_index() == index, "sanity"); + return hr; +} + +inline void HeapRegionManager::insert_into_free_list(HeapRegion* hr) { + _free_list.add_ordered(hr); +} + +inline void HeapRegionManager::allocate_free_regions_starting_at(uint first, uint num_regions) { + _free_list.remove_starting_at(at(first), num_regions); +} + +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP