--- a/hotspot/src/share/vm/gc/shared/allocTracer.cpp Fri Jan 01 17:08:38 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/allocTracer.cpp Mon Jan 04 11:27:02 2016 +0100
@@ -46,3 +46,12 @@
event.commit();
}
}
+
+void AllocTracer::send_allocation_requiring_gc_event(size_t size, uint gcId) {
+ EventAllocationRequiringGC event;
+ if (event.should_commit()) {
+ event.set_gcId(gcId);
+ event.set_size(size);
+ event.commit();
+ }
+}
--- a/hotspot/src/share/vm/gc/shared/allocTracer.hpp Fri Jan 01 17:08:38 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/allocTracer.hpp Mon Jan 04 11:27:02 2016 +0100
@@ -32,6 +32,7 @@
public:
static void send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size);
static void send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size);
+ static void send_allocation_requiring_gc_event(size_t size, uint gcId);
};
#endif // SHARE_VM_GC_SHARED_ALLOCTRACER_HPP
--- a/hotspot/src/share/vm/gc/shared/gcId.cpp Fri Jan 01 17:08:38 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/gcId.cpp Mon Jan 04 11:27:02 2016 +0100
@@ -39,6 +39,10 @@
return _next_id++;
}
+const uint GCId::peek() {
+ return _next_id;
+}
+
const uint GCId::current() {
assert(currentNamedthread()->gc_id() != undefined(), "Using undefined GC id.");
return current_raw();
--- a/hotspot/src/share/vm/gc/shared/gcId.hpp Fri Jan 01 17:08:38 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/gcId.hpp Mon Jan 04 11:27:02 2016 +0100
@@ -39,6 +39,8 @@
static const uint current();
// Same as current() but can return undefined() if no GC id is currently active
static const uint current_raw();
+ // Returns the next expected GCId.
+ static const uint peek();
static const uint undefined() { return UNDEFINED; }
static size_t print_prefix(char* buf, size_t len);
};
--- a/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp Fri Jan 01 17:08:38 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp Mon Jan 04 11:27:02 2016 +0100
@@ -25,6 +25,8 @@
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/javaClasses.hpp"
+#include "gc/shared/allocTracer.hpp"
+#include "gc/shared/gcId.hpp"
#include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/vmGCOperations.hpp"
@@ -188,6 +190,18 @@
gch->do_full_collection(gch->must_clear_all_soft_refs(), _max_generation);
}
+VM_CollectForMetadataAllocation::VM_CollectForMetadataAllocation(ClassLoaderData* loader_data,
+ size_t size,
+ Metaspace::MetadataType mdtype,
+ uint gc_count_before,
+ uint full_gc_count_before,
+ GCCause::Cause gc_cause)
+ : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true),
+ _loader_data(loader_data), _size(size), _mdtype(mdtype), _result(NULL) {
+ assert(_size != 0, "An allocation should always be requested with this operation.");
+ AllocTracer::send_allocation_requiring_gc_event(_size * HeapWordSize, GCId::peek());
+}
+
// Returns true iff concurrent GCs unloads metadata.
bool VM_CollectForMetadataAllocation::initiate_concurrent_GC() {
#if INCLUDE_ALL_GCS
@@ -279,3 +293,11 @@
set_gc_locked();
}
}
+
+VM_CollectForAllocation::VM_CollectForAllocation(size_t word_size, uint gc_count_before, GCCause::Cause cause)
+ : VM_GC_Operation(gc_count_before, cause), _result(NULL), _word_size(word_size) {
+ // Only report if operation was really caused by an allocation.
+ if (_word_size != 0) {
+ AllocTracer::send_allocation_requiring_gc_event(_word_size * HeapWordSize, GCId::peek());
+ }
+}
--- a/hotspot/src/share/vm/gc/shared/vmGCOperations.hpp Fri Jan 01 17:08:38 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/vmGCOperations.hpp Mon Jan 04 11:27:02 2016 +0100
@@ -166,8 +166,7 @@
HeapWord* _result; // Allocation result (NULL if allocation failed)
public:
- VM_CollectForAllocation(size_t word_size, uint gc_count_before, GCCause::Cause cause)
- : VM_GC_Operation(gc_count_before, cause), _result(NULL), _word_size(word_size) {}
+ VM_CollectForAllocation(size_t word_size, uint gc_count_before, GCCause::Cause cause);
HeapWord* result() const {
return _result;
@@ -220,10 +219,7 @@
Metaspace::MetadataType mdtype,
uint gc_count_before,
uint full_gc_count_before,
- GCCause::Cause gc_cause)
- : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true),
- _loader_data(loader_data), _size(size), _mdtype(mdtype), _result(NULL) {
- }
+ GCCause::Cause gc_cause);
virtual VMOp_Type type() const { return VMOp_CollectForMetadataAllocation; }
virtual void doit();
--- a/hotspot/src/share/vm/trace/trace.xml Fri Jan 01 17:08:38 2016 +0000
+++ b/hotspot/src/share/vm/trace/trace.xml Mon Jan 04 11:27:02 2016 +0100
@@ -465,6 +465,12 @@
<value type="UTF8" field="name" label="Name" />
</event>
+ <event id="AllocationRequiringGC" path="vm/gc/detailed/allocation_requiring_gc" label="Allocation Requiring GC"
+ has_thread="true" has_stacktrace="true" is_instant="true">
+ <value type="UINT" field="gcId" label="Pending GC ID" relation="GC_ID" />
+ <value type="BYTES64" field="size" label="Allocation Size" />
+ </event>
+
<!-- Compiler events -->
<event id="Compilation" path="vm/compiler/compilation" label="Compilation"