8149650: Create a trace event for G1 heap region type transitions
Reviewed-by: jwilhelm, sjohanss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/G1HeapRegionType.java Fri Feb 12 09:19:10 2016 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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.shared;
+
+//These definitions should be kept in sync with the definitions in the HotSpot code.
+
+public enum G1HeapRegionType {
+ Free ("Free"),
+ Eden ("Eden"),
+ Survivor ("Survivor"),
+ StartsHumongous ("Starts Humongous"),
+ ContinuesHumongous ("Continues Humongous"),
+ Old ("Old"),
+ Archive ("Archive"),
+ G1HeapRegionTypeEndSentinel ("G1HeapRegionTypeEndSentinel");
+
+ private final String value;
+
+ G1HeapRegionType(String val) {
+ this.value = val;
+ }
+ public String value() {
+ return value;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1HeapRegionTraceType.hpp Fri Feb 12 09:19:10 2016 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, 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_G1_G1HEAPREGIONTRACETYPE_HPP
+#define SHARE_VM_GC_G1_G1HEAPREGIONTRACETYPE_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+
+class G1HeapRegionTraceType : AllStatic {
+ public:
+ enum Type {
+ Free,
+ Eden,
+ Survivor,
+ StartsHumongous,
+ ContinuesHumongous,
+ Old,
+ Archive,
+ G1HeapRegionTypeEndSentinel
+ };
+
+ static const char* to_string(G1HeapRegionTraceType::Type type) {
+ switch (type) {
+ case Free: return "Free";
+ case Eden: return "Eden";
+ case Survivor: return "Survivor";
+ case StartsHumongous: return "Starts Humongous";
+ case ContinuesHumongous: return "Continues Humongous";
+ case Old: return "Old";
+ case Archive: return "Archive";
+ default: ShouldNotReachHere(); return NULL;
+ }
+ }
+};
+
+#endif // SHARE_VM_GC_G1_G1HEAPREGIONTRACETYPE_HPP
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp Fri Feb 12 09:12:12 2016 +0100
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp Fri Feb 12 09:19:10 2016 +0100
@@ -26,11 +26,13 @@
#include "code/nmethod.hpp"
#include "gc/g1/g1BlockOffsetTable.inline.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1HeapRegionTraceType.hpp"
#include "gc/g1/g1OopClosures.inline.hpp"
#include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionBounds.inline.hpp"
#include "gc/g1/heapRegionManager.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/g1/heapRegionTracer.hpp"
#include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/liveRange.hpp"
#include "gc/shared/space.inline.hpp"
@@ -212,10 +214,41 @@
_gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms;
}
+void HeapRegion::set_free() {
+ report_region_type_change(G1HeapRegionTraceType::Free);
+ _type.set_free();
+}
+
+void HeapRegion::set_eden() {
+ report_region_type_change(G1HeapRegionTraceType::Eden);
+ _type.set_eden();
+}
+
+void HeapRegion::set_eden_pre_gc() {
+ report_region_type_change(G1HeapRegionTraceType::Eden);
+ _type.set_eden_pre_gc();
+}
+
+void HeapRegion::set_survivor() {
+ report_region_type_change(G1HeapRegionTraceType::Survivor);
+ _type.set_survivor();
+}
+
+void HeapRegion::set_old() {
+ report_region_type_change(G1HeapRegionTraceType::Old);
+ _type.set_old();
+}
+
+void HeapRegion::set_archive() {
+ report_region_type_change(G1HeapRegionTraceType::Archive);
+ _type.set_archive();
+}
+
void HeapRegion::set_starts_humongous(HeapWord* obj_top, size_t fill_size) {
assert(!is_humongous(), "sanity / pre-condition");
assert(top() == bottom(), "should be empty");
+ report_region_type_change(G1HeapRegionTraceType::StartsHumongous);
_type.set_starts_humongous();
_humongous_start_region = this;
@@ -227,6 +260,7 @@
assert(top() == bottom(), "should be empty");
assert(first_hr->is_starts_humongous(), "pre-condition");
+ report_region_type_change(G1HeapRegionTraceType::ContinuesHumongous);
_type.set_continues_humongous();
_humongous_start_region = first_hr;
}
@@ -272,6 +306,15 @@
record_timestamp();
}
+void HeapRegion::report_region_type_change(G1HeapRegionTraceType::Type to) {
+ HeapRegionTracer::send_region_type_change(_hrm_index,
+ get_trace_type(),
+ to,
+ (uintptr_t)bottom(),
+ used(),
+ (uint)allocation_context());
+}
+
CompactibleSpace* HeapRegion::next_compaction_space() const {
return G1CollectedHeap::heap()->next_compaction_region(this);
}
--- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp Fri Feb 12 09:12:12 2016 +0100
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp Fri Feb 12 09:19:10 2016 +0100
@@ -27,6 +27,8 @@
#include "gc/g1/g1AllocationContext.hpp"
#include "gc/g1/g1BlockOffsetTable.hpp"
+#include "gc/g1/g1HeapRegionTraceType.hpp"
+#include "gc/g1/heapRegionTracer.hpp"
#include "gc/g1/heapRegionType.hpp"
#include "gc/g1/survRateGroup.hpp"
#include "gc/shared/ageTable.hpp"
@@ -243,6 +245,8 @@
return HeapRegion::block_size(addr); // Avoid virtual call
}
+ void report_region_type_change(G1HeapRegionTraceType::Type to);
+
protected:
// The index of this region in the heap region sequence.
uint _hrm_index;
@@ -427,6 +431,7 @@
const char* get_type_str() const { return _type.get_str(); }
const char* get_short_type_str() const { return _type.get_short_str(); }
+ G1HeapRegionTraceType::Type get_trace_type() { return _type.get_trace_type(); }
bool is_free() const { return _type.is_free(); }
@@ -637,15 +642,15 @@
}
}
- void set_free() { _type.set_free(); }
+ void set_free();
- void set_eden() { _type.set_eden(); }
- void set_eden_pre_gc() { _type.set_eden_pre_gc(); }
- void set_survivor() { _type.set_survivor(); }
+ void set_eden();
+ void set_eden_pre_gc();
+ void set_survivor();
- void set_old() { _type.set_old(); }
+ void set_old();
- void set_archive() { _type.set_archive(); }
+ void set_archive();
// Determine if an object has been allocated since the last
// mark performed by the collector. This returns true iff the object
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/heapRegionTracer.cpp Fri Feb 12 09:19:10 2016 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/heapRegionTracer.hpp"
+#include "trace/tracing.hpp"
+
+void HeapRegionTracer::send_region_type_change(uint index,
+ G1HeapRegionTraceType::Type from,
+ G1HeapRegionTraceType::Type to,
+ uintptr_t start,
+ size_t used,
+ uint allocationContext) {
+ EventG1HeapRegionTypeChange e;
+ if (e.should_commit()) {
+ e.set_index(index);
+ e.set_from(from);
+ e.set_to(to);
+ e.set_start(start);
+ e.set_used(used);
+ e.set_allocContext(allocationContext);
+ e.commit();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/heapRegionTracer.hpp Fri Feb 12 09:19:10 2016 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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_G1_HEAPREGIONTRACER_HPP
+#define SHARE_VM_GC_G1_HEAPREGIONTRACER_HPP
+
+#include "gc/g1/g1HeapRegionTraceType.hpp"
+#include "memory/allocation.hpp"
+
+class HeapRegionTracer : AllStatic {
+ public:
+ static void send_region_type_change(uint index,
+ G1HeapRegionTraceType::Type from,
+ G1HeapRegionTraceType::Type to,
+ uintptr_t start,
+ size_t used,
+ uint allocationContext);
+};
+
+#endif // SHARE_VM_GC_G1_HEAPREGIONTRACER_HPP
--- a/hotspot/src/share/vm/gc/g1/heapRegionType.cpp Fri Feb 12 09:12:12 2016 +0100
+++ b/hotspot/src/share/vm/gc/g1/heapRegionType.cpp Fri Feb 12 09:19:10 2016 +0100
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "gc/g1/g1HeapRegionTraceType.hpp"
#include "gc/g1/heapRegionType.hpp"
bool HeapRegionType::is_valid(Tag tag) {
@@ -70,3 +71,19 @@
// keep some compilers happy
return NULL;
}
+
+G1HeapRegionTraceType::Type HeapRegionType::get_trace_type() {
+ hrt_assert_is_valid(_tag);
+ switch (_tag) {
+ case FreeTag: return G1HeapRegionTraceType::Free;
+ case EdenTag: return G1HeapRegionTraceType::Eden;
+ case SurvTag: return G1HeapRegionTraceType::Survivor;
+ case StartsHumongousTag: return G1HeapRegionTraceType::StartsHumongous;
+ case ContinuesHumongousTag: return G1HeapRegionTraceType::ContinuesHumongous;
+ case OldTag: return G1HeapRegionTraceType::Old;
+ case ArchiveTag: return G1HeapRegionTraceType::Archive;
+ }
+ ShouldNotReachHere();
+ // keep some compilers happy
+ return G1HeapRegionTraceType::Free;
+}
--- a/hotspot/src/share/vm/gc/g1/heapRegionType.hpp Fri Feb 12 09:12:12 2016 +0100
+++ b/hotspot/src/share/vm/gc/g1/heapRegionType.hpp Fri Feb 12 09:19:10 2016 +0100
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_GC_G1_HEAPREGIONTYPE_HPP
#define SHARE_VM_GC_G1_HEAPREGIONTYPE_HPP
+#include "gc/g1/g1HeapRegionTraceType.hpp"
#include "memory/allocation.hpp"
#define hrt_assert_is_valid(tag) \
@@ -141,6 +142,7 @@
const char* get_str() const;
const char* get_short_str() const;
+ G1HeapRegionTraceType::Type get_trace_type();
HeapRegionType() : _tag(FreeTag) { hrt_assert_is_valid(_tag); }
};
--- a/hotspot/src/share/vm/trace/trace.xml Fri Feb 12 09:12:12 2016 +0100
+++ b/hotspot/src/share/vm/trace/trace.xml Fri Feb 12 09:19:10 2016 +0100
@@ -486,6 +486,16 @@
<value type="BYTES64" field="size" label="Size" />
</event>
+ <event id="G1HeapRegionTypeChange" path="vm/gc/detailed/g1_heap_region_type_change" label="G1 Heap Region Type Change"
+ description="Information about a G1 heap region type change." is_instant="true">
+ <value type="UINT" field="index" label="Index" />
+ <value type="G1HEAPREGIONTYPE" field="from" label="From Type" />
+ <value type="G1HEAPREGIONTYPE" field="to" label="To Type" />
+ <value type="ADDRESS" field="start" label="Start" />
+ <value type="BYTES64" field="used" label="Used" />
+ <value type="UINT" field="allocContext" label="Allocation Context" />
+ </event>
+
<!-- Compiler events -->
<event id="Compilation" path="vm/compiler/compilation" label="Compilation"
--- a/hotspot/src/share/vm/trace/tracetypes.xml Fri Feb 12 09:12:12 2016 +0100
+++ b/hotspot/src/share/vm/trace/tracetypes.xml Fri Feb 12 09:19:10 2016 +0100
@@ -126,6 +126,11 @@
<value type="UTF8" field="when" label="when" />
</content_type>
+ <content_type id="G1HeapRegionType" hr_name="G1 Heap Region Type"
+ type="U1" jvm_type="G1HEAPREGIONTYPE">
+ <value type="UTF8" field="type" label="type" />
+ </content_type>
+
<content_type id="G1YCType" hr_name="G1 YC Type"
type="U1" jvm_type="G1YCTYPE">
<value type="UTF8" field="type" label="type" />
@@ -345,6 +350,10 @@
<primary_type symbol="GCWHEN" datatype="U1" contenttype="GCWHEN"
type="u1" sizeop="sizeof(u1)" />
+ <!-- G1HEAPREGIONTYPE -->
+ <primary_type symbol="G1HEAPREGIONTYPE" datatype="U1" contenttype="G1HEAPREGIONTYPE"
+ type="u1" sizeop="sizeof(u1)" />
+
<!-- G1YCType -->
<primary_type symbol="G1YCTYPE" datatype="U1" contenttype="G1YCTYPE"
type="u1" sizeop="sizeof(u1)" />