# HG changeset patch # User david # Date 1449835928 -3600 # Fri Dec 11 13:12:08 2015 +0100 # Node ID e8af4f9f641d1d91ead9428f8c988671118a38ec # Parent 1fd6f49c4b510b24d35fa4108f2c383e81f0d4f1 [mq]: HeapRegionCount diff --git a/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetBase.java b/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetBase.java --- a/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetBase.java +++ b/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetBase.java @@ -41,7 +41,8 @@ public class HeapRegionSetBase extends VMObject { - static private long countField; + // uint _length + static private CIntegerField lengthField; static { VM.registerVMInitializedObserver(new Observer() { @@ -54,13 +55,11 @@ static private synchronized void initialize(TypeDataBase db) { Type type = db.lookupType("HeapRegionSetBase"); - countField = type.getField("_count").getOffset(); + lengthField = type.getCIntegerField("_length"); } - - public HeapRegionSetCount count() { - Address countFieldAddr = addr.addOffsetTo(countField); - return (HeapRegionSetCount) VMObjectFactory.newObject(HeapRegionSetCount.class, countFieldAddr); + public long length() { + return lengthField.getValue(addr); } public HeapRegionSetBase(Address addr) { diff --git a/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetCount.java b/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetCount.java deleted file mode 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetCount.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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.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 HeapRegionSetCount. Represents a group of regions. - -public class HeapRegionSetCount extends VMObject { - - static private CIntegerField lengthField; - static private CIntegerField capacityField; - - 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("HeapRegionSetCount"); - - lengthField = type.getCIntegerField("_length"); - capacityField = type.getCIntegerField("_capacity"); - } - - public long length() { - return lengthField.getValue(addr); - } - - public long capacity() { - return capacityField.getValue(addr); - } - - public HeapRegionSetCount(Address addr) { - super(addr); - } -} diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -112,8 +112,7 @@ long survivorRegionNum = g1mm.survivorRegionNum(); HeapRegionSetBase oldSet = g1h.oldSet(); HeapRegionSetBase humongousSet = g1h.humongousSet(); - long oldRegionNum = oldSet.count().length() - + humongousSet.count().capacity() / HeapRegion.grainBytes(); + long oldRegionNum = oldSet.length() + humongousSet.length(); printG1Space("G1 Heap:", g1h.n_regions(), g1h.used(), g1h.capacity()); System.out.println("G1 Young Generation:"); diff --git a/src/share/vm/gc/g1/concurrentMark.cpp b/src/share/vm/gc/g1/concurrentMark.cpp --- a/src/share/vm/gc/g1/concurrentMark.cpp +++ b/src/share/vm/gc/g1/concurrentMark.cpp @@ -1483,8 +1483,8 @@ G1CollectedHeap* _g1; size_t _freed_bytes; FreeRegionList* _local_cleanup_list; - HeapRegionSetCount _old_regions_removed; - HeapRegionSetCount _humongous_regions_removed; + uint _old_regions_removed; + uint _humongous_regions_removed; HRRSCleanupTask* _hrrs_cleanup_task; public: @@ -1494,13 +1494,13 @@ _g1(g1), _freed_bytes(0), _local_cleanup_list(local_cleanup_list), - _old_regions_removed(), - _humongous_regions_removed(), + _old_regions_removed(0), + _humongous_regions_removed(0), _hrrs_cleanup_task(hrrs_cleanup_task) { } size_t freed_bytes() { return _freed_bytes; } - const HeapRegionSetCount& old_regions_removed() { return _old_regions_removed; } - const HeapRegionSetCount& humongous_regions_removed() { return _humongous_regions_removed; } + const uint old_regions_removed() { return _old_regions_removed; } + const uint humongous_regions_removed() { return _humongous_regions_removed; } bool doHeapRegion(HeapRegion *hr) { if (hr->is_archive()) { @@ -1515,10 +1515,10 @@ _freed_bytes += hr->used(); hr->set_containing_set(NULL); if (hr->is_humongous()) { - _humongous_regions_removed.increment(1u, hr->capacity()); + _humongous_regions_removed++; _g1->free_humongous_region(hr, _local_cleanup_list, true); } else { - _old_regions_removed.increment(1u, hr->capacity()); + _old_regions_removed++; _g1->free_region(hr, _local_cleanup_list, true); } } else { diff --git a/src/share/vm/gc/g1/g1CollectedHeap.cpp b/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -5195,9 +5195,9 @@ free_region(hr, free_list, par); } -void G1CollectedHeap::remove_from_old_sets(const HeapRegionSetCount& old_regions_removed, - const HeapRegionSetCount& humongous_regions_removed) { - if (old_regions_removed.length() > 0 || humongous_regions_removed.length() > 0) { +void G1CollectedHeap::remove_from_old_sets(const uint old_regions_removed, + const uint humongous_regions_removed) { + if (old_regions_removed > 0 || humongous_regions_removed > 0) { MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); _old_set.bulk_remove(old_regions_removed); _humongous_set.bulk_remove(humongous_regions_removed); @@ -5582,12 +5582,12 @@ private: FreeRegionList* _free_region_list; HeapRegionSet* _proxy_set; - HeapRegionSetCount _humongous_regions_removed; + uint _humongous_regions_removed; size_t _freed_bytes; public: G1FreeHumongousRegionClosure(FreeRegionList* free_region_list) : - _free_region_list(free_region_list), _humongous_regions_removed(), _freed_bytes(0) { + _free_region_list(free_region_list), _humongous_regions_removed(0), _freed_bytes(0) { } virtual bool doHeapRegion(HeapRegion* r) { @@ -5667,7 +5667,7 @@ HeapRegion* next = g1h->next_region_in_humongous(r); _freed_bytes += r->used(); r->set_containing_set(NULL); - _humongous_regions_removed.increment(1u, r->capacity()); + _humongous_regions_removed++; g1h->free_humongous_region(r, _free_region_list, false); r = next; } while (r != NULL); @@ -5675,17 +5675,13 @@ return false; } - HeapRegionSetCount& humongous_free_count() { + uint humongous_free_count() { return _humongous_regions_removed; } size_t bytes_freed() const { return _freed_bytes; } - - size_t humongous_reclaimed() const { - return _humongous_regions_removed.length(); - } }; void G1CollectedHeap::eagerly_reclaim_humongous_regions() { @@ -5704,8 +5700,7 @@ G1FreeHumongousRegionClosure cl(&local_cleanup_list); heap_region_iterate(&cl); - HeapRegionSetCount empty_set; - remove_from_old_sets(empty_set, cl.humongous_free_count()); + remove_from_old_sets(0, cl.humongous_free_count()); G1HRPrinter* hrp = hr_printer(); if (hrp->is_active()) { @@ -5720,7 +5715,7 @@ decrement_summary_bytes(cl.bytes_freed()); g1_policy()->phase_times()->record_fast_reclaim_humongous_time_ms((os::elapsedTime() - start_time) * 1000.0, - cl.humongous_reclaimed()); + cl.humongous_free_count()); } // This routine is similar to the above but does not record @@ -6066,9 +6061,9 @@ HeapRegionManager* _hrm; public: - HeapRegionSetCount _old_count; - HeapRegionSetCount _humongous_count; - HeapRegionSetCount _free_count; + uint _old_count; + uint _humongous_count; + uint _free_count; VerifyRegionListsClosure(HeapRegionSet* old_set, HeapRegionSet* humongous_set, @@ -6081,13 +6076,13 @@ // TODO } else if (hr->is_humongous()) { assert(hr->containing_set() == _humongous_set, "Heap region %u is humongous but not in humongous set.", hr->hrm_index()); - _humongous_count.increment(1u, hr->capacity()); + _humongous_count++; } else if (hr->is_empty()) { assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index()); - _free_count.increment(1u, hr->capacity()); + _free_count++; } else if (hr->is_old()) { assert(hr->containing_set() == _old_set, "Heap region %u is old but not in the old set.", hr->hrm_index()); - _old_count.increment(1u, hr->capacity()); + _old_count++; } else { // There are no other valid region types. Check for one invalid // one we can identify: pinned without old or humongous set. @@ -6098,17 +6093,9 @@ } void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) { - guarantee(old_set->length() == _old_count.length(), "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length()); - guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), "Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, - old_set->total_capacity_bytes(), _old_count.capacity()); - - guarantee(humongous_set->length() == _humongous_count.length(), "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count.length()); - guarantee(humongous_set->total_capacity_bytes() == _humongous_count.capacity(), "Hum set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, - humongous_set->total_capacity_bytes(), _humongous_count.capacity()); - - guarantee(free_list->num_free_regions() == _free_count.length(), "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count.length()); - guarantee(free_list->total_capacity_bytes() == _free_count.capacity(), "Free list capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, - free_list->total_capacity_bytes(), _free_count.capacity()); + guarantee(old_set->length() == _old_count, "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count); + guarantee(humongous_set->length() == _humongous_count, "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count); + guarantee(free_list->num_free_regions() == _free_count, "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count); } }; diff --git a/src/share/vm/gc/g1/g1CollectedHeap.hpp b/src/share/vm/gc/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc/g1/g1CollectedHeap.hpp +++ b/src/share/vm/gc/g1/g1CollectedHeap.hpp @@ -1132,7 +1132,7 @@ inline void old_set_remove(HeapRegion* hr); size_t non_young_capacity_bytes() { - return _old_set.total_capacity_bytes() + _humongous_set.total_capacity_bytes(); + return (_old_set.length() + _humongous_set.length()) * HeapRegion::GrainBytes; } void set_free_regions_coming(); @@ -1157,7 +1157,7 @@ // True iff an evacuation has failed in the most-recent collection. bool evacuation_failed() { return _evacuation_failed; } - void remove_from_old_sets(const HeapRegionSetCount& old_regions_removed, const HeapRegionSetCount& humongous_regions_removed); + void remove_from_old_sets(const uint old_regions_removed, const uint humongous_regions_removed); void prepend_to_freelist(FreeRegionList* list); void decrement_summary_bytes(size_t bytes); diff --git a/src/share/vm/gc/g1/g1MarkSweep.cpp b/src/share/vm/gc/g1/g1MarkSweep.cpp --- a/src/share/vm/gc/g1/g1MarkSweep.cpp +++ b/src/share/vm/gc/g1/g1MarkSweep.cpp @@ -329,7 +329,7 @@ FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep"); hr->set_containing_set(NULL); - _humongous_regions_removed.increment(1u, hr->capacity()); + _humongous_regions_removed++; _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */); prepare_for_compaction(hr, end); @@ -358,8 +358,7 @@ void G1PrepareCompactClosure::update_sets() { // We'll recalculate total used bytes and recreate the free list // at the end of the GC, so no point in updating those values here. - HeapRegionSetCount empty_set; - _g1h->remove_from_old_sets(empty_set, _humongous_regions_removed); + _g1h->remove_from_old_sets(0, _humongous_regions_removed); } bool G1PrepareCompactClosure::doHeapRegion(HeapRegion* hr) { diff --git a/src/share/vm/gc/g1/g1MarkSweep.hpp b/src/share/vm/gc/g1/g1MarkSweep.hpp --- a/src/share/vm/gc/g1/g1MarkSweep.hpp +++ b/src/share/vm/gc/g1/g1MarkSweep.hpp @@ -92,7 +92,7 @@ G1CollectedHeap* _g1h; ModRefBarrierSet* _mrbs; CompactPoint _cp; - HeapRegionSetCount _humongous_regions_removed; + uint _humongous_regions_removed; virtual void prepare_for_compaction(HeapRegion* hr, HeapWord* end); void prepare_for_compaction_work(CompactPoint* cp, HeapRegion* hr, HeapWord* end); @@ -103,7 +103,7 @@ G1PrepareCompactClosure() : _g1h(G1CollectedHeap::heap()), _mrbs(_g1h->g1_barrier_set()), - _humongous_regions_removed() { } + _humongous_regions_removed(0) { } void update_sets(); bool doHeapRegion(HeapRegion* hr); diff --git a/src/share/vm/gc/g1/heapRegionSet.cpp b/src/share/vm/gc/g1/heapRegionSet.cpp --- a/src/share/vm/gc/g1/heapRegionSet.cpp +++ b/src/share/vm/gc/g1/heapRegionSet.cpp @@ -49,8 +49,8 @@ // verification might fail and send us on a wild goose chase. check_mt_safety(); - guarantee_heap_region_set(( is_empty() && length() == 0 && total_capacity_bytes() == 0) || - (!is_empty() && length() > 0 && total_capacity_bytes() > 0) , + guarantee_heap_region_set(( is_empty() && length() == 0) || + (!is_empty() && length() > 0), "invariant"); } @@ -81,14 +81,12 @@ out->print_cr(" free : %s", BOOL_TO_STR(regions_free())); out->print_cr(" Attributes"); out->print_cr(" length : %14u", length()); - out->print_cr(" total capacity : " SIZE_FORMAT_W(14) " bytes", - total_capacity_bytes()); } HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker) : _name(name), _verify_in_progress(false), _is_humongous(humongous), _is_free(free), _mt_safety_checker(mt_safety_checker), - _count() + _length(0) { } void FreeRegionList::set_unrealistically_long_length(uint len) { @@ -177,7 +175,7 @@ } } - _count.increment(from_list->length(), from_list->total_capacity_bytes()); + _length += from_list->length(); from_list->clear(); verify_optional(); @@ -255,7 +253,7 @@ } void FreeRegionList::clear() { - _count = HeapRegionSetCount(); + _length = 0; _head = NULL; _tail = NULL; _last = NULL; @@ -294,8 +292,6 @@ guarantee(_tail == prev0, "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, "%s count mismatch. Expected %u, actual %u.", name(), length(), count); - guarantee(total_capacity_bytes() == capacity, "%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, - name(), total_capacity_bytes(), capacity); } // Note on the check_mt_safety() methods below: diff --git a/src/share/vm/gc/g1/heapRegionSet.hpp b/src/share/vm/gc/g1/heapRegionSet.hpp --- a/src/share/vm/gc/g1/heapRegionSet.hpp +++ b/src/share/vm/gc/g1/heapRegionSet.hpp @@ -27,22 +27,22 @@ #include "gc/g1/heapRegion.hpp" -#define assert_heap_region_set(p, message) \ - do { \ - assert((p), "[%s] %s ln: %u cy: " SIZE_FORMAT, \ - name(), message, length(), total_capacity_bytes()); \ +#define assert_heap_region_set(p, message) \ + do { \ + assert((p), "[%s] %s ln: %u", \ + name(), message, length()); \ } while (0) -#define guarantee_heap_region_set(p, message) \ - do { \ - guarantee((p), "[%s] %s ln: %u cy: " SIZE_FORMAT, \ - name(), message, length(), total_capacity_bytes()); \ +#define guarantee_heap_region_set(p, message) \ + do { \ + guarantee((p), "[%s] %s ln: %u", \ + name(), message, length()); \ } while (0) -#define assert_free_region_list(p, message) \ - do { \ - assert((p), "[%s] %s ln: %u cy: " SIZE_FORMAT " hd: " PTR_FORMAT " tl: " PTR_FORMAT, \ - name(), message, length(), total_capacity_bytes(), p2i(_head), p2i(_tail)); \ +#define assert_free_region_list(p, message) \ + do { \ + assert((p), "[%s] %s ln: %u hd: " PTR_FORMAT " tl: " PTR_FORMAT, \ + name(), message, length(), p2i(_head), p2i(_tail)); \ } while (0) @@ -63,28 +63,6 @@ class HumongousRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); }; class OldRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); }; -class HeapRegionSetCount VALUE_OBJ_CLASS_SPEC { - friend class VMStructs; - uint _length; - size_t _capacity; - -public: - HeapRegionSetCount() : _length(0), _capacity(0) { } - - const uint length() const { return _length; } - const size_t capacity() const { return _capacity; } - - void increment(uint length_to_add, size_t capacity_to_add) { - _length += length_to_add; - _capacity += capacity_to_add; - } - - void decrement(const uint length_to_remove, const size_t capacity_to_remove) { - _length -= length_to_remove; - _capacity -= capacity_to_remove; - } -}; - // Base class for all the classes that represent heap region sets. It // contains the basic attributes that each set needs to maintain // (e.g., length, region num, used bytes sum) plus any shared @@ -98,10 +76,8 @@ HRSMtSafeChecker* _mt_safety_checker; protected: - // The number of regions added to the set. If the set contains - // only humongous regions, this reflects only 'starts humongous' - // regions and does not include 'continues humongous' ones. - HeapRegionSetCount _count; + // The number of regions in to the set. + uint _length; const char* _name; @@ -130,13 +106,9 @@ public: const char* name() { return _name; } - uint length() const { return _count.length(); } + uint length() const { return _length; } - bool is_empty() { return _count.length() == 0; } - - size_t total_capacity_bytes() { - return _count.capacity(); - } + bool is_empty() { return _length == 0; } // It updates the fields of the set to reflect hr being added to // the set and tags the region appropriately. @@ -181,8 +153,8 @@ HeapRegionSet(const char* name, bool humongous, HRSMtSafeChecker* mt_safety_checker): HeapRegionSetBase(name, humongous, false /* free */, mt_safety_checker) { } - void bulk_remove(const HeapRegionSetCount& removed) { - _count.decrement(removed.length(), removed.capacity()); + void bulk_remove(const uint removed) { + _length -= removed; } }; diff --git a/src/share/vm/gc/g1/heapRegionSet.inline.hpp b/src/share/vm/gc/g1/heapRegionSet.inline.hpp --- a/src/share/vm/gc/g1/heapRegionSet.inline.hpp +++ b/src/share/vm/gc/g1/heapRegionSet.inline.hpp @@ -33,7 +33,7 @@ assert_heap_region_set(hr->next() == NULL, "should not already be linked"); assert_heap_region_set(hr->prev() == NULL, "should not already be linked"); - _count.increment(1u, hr->capacity()); + _length++; hr->set_containing_set(this); verify_region(hr); } @@ -45,8 +45,8 @@ assert_heap_region_set(hr->prev() == NULL, "should already be unlinked"); hr->set_containing_set(NULL); - assert_heap_region_set(_count.length() > 0, "pre-condition"); - _count.decrement(1u, hr->capacity()); + assert_heap_region_set(_length > 0, "pre-condition"); + _length--; } inline void FreeRegionList::add_ordered(HeapRegion* hr) { diff --git a/src/share/vm/gc/g1/vmStructs_g1.hpp b/src/share/vm/gc/g1/vmStructs_g1.hpp --- a/src/share/vm/gc/g1/vmStructs_g1.hpp +++ b/src/share/vm/gc/g1/vmStructs_g1.hpp @@ -59,10 +59,7 @@ nonstatic_field(G1MonitoringSupport, _old_committed, size_t) \ nonstatic_field(G1MonitoringSupport, _old_used, size_t) \ \ - nonstatic_field(HeapRegionSetBase, _count, HeapRegionSetCount) \ - \ - nonstatic_field(HeapRegionSetCount, _length, uint) \ - nonstatic_field(HeapRegionSetCount, _capacity, size_t) \ + nonstatic_field(HeapRegionSetBase, _length, uint) \ \ nonstatic_field(PtrQueue, _active, bool) \ nonstatic_field(PtrQueue, _buf, void**) \ @@ -103,7 +100,6 @@ declare_type(HeapRegion, G1OffsetTableContigSpace) \ declare_toplevel_type(HeapRegionManager) \ declare_toplevel_type(HeapRegionSetBase) \ - declare_toplevel_type(HeapRegionSetCount) \ declare_toplevel_type(G1MonitoringSupport) \ declare_toplevel_type(PtrQueue) \ \