--- a/src/hotspot/share/prims/jvmtiExport.hpp Mon Jun 11 15:28:24 2018 +0200
+++ b/src/hotspot/share/prims/jvmtiExport.hpp Fri Jun 15 00:49:54 2018 -0700
@@ -123,6 +123,7 @@
// breakpoint info
JVMTI_SUPPORT_FLAG(should_clean_up_heap_objects)
JVMTI_SUPPORT_FLAG(should_post_vm_object_alloc)
+ JVMTI_SUPPORT_FLAG(should_post_sampled_object_alloc)
// If flag cannot be implemented, give an error if on=true
static void report_unsupported(bool on);
@@ -363,6 +364,18 @@
record_vm_internal_object_allocation(object);
}
}
+
+ static void record_sampled_internal_object_allocation(oop object) NOT_JVMTI_RETURN;
+ // Post objects collected by sampled_object_alloc_event_collector.
+ static void post_sampled_object_alloc(JavaThread *thread, oop object) NOT_JVMTI_RETURN;
+
+ // Collects vm internal objects for later event posting.
+ inline static void sampled_object_alloc_event_collector(oop object) {
+ if (should_post_sampled_object_alloc()) {
+ record_sampled_internal_object_allocation(object);
+ }
+ }
+
inline static void post_array_size_exhausted() {
if (should_post_resource_exhausted()) {
post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
@@ -422,12 +435,16 @@
class JvmtiEventCollector : public StackObj {
private:
JvmtiEventCollector* _prev; // Save previous one to support nested event collector.
+ bool _unset_jvmti_thread_state;
public:
- void setup_jvmti_thread_state(); // Set this collector in current thread.
+ JvmtiEventCollector() : _prev(NULL), _unset_jvmti_thread_state(false) {}
+
+ void setup_jvmti_thread_state(); // Set this collector in current thread, returns if success.
void unset_jvmti_thread_state(); // Reset previous collector in current thread.
virtual bool is_dynamic_code_event() { return false; }
virtual bool is_vm_object_alloc_event(){ return false; }
+ virtual bool is_sampled_object_alloc_event(){ return false; }
JvmtiEventCollector *get_prev() { return _prev; }
};
@@ -462,42 +479,67 @@
};
-// Used to record vm internally allocated object oops and post
-// vm object alloc event for objects visible to java world.
-// Constructor enables JvmtiThreadState flag and all vm allocated
-// objects are recorded in a growable array. When destructor is
-// called the vm object alloc event is posted for each objects
-// visible to java world.
-// See jvm.cpp file for its usage.
+// Used as a base class for object allocation collection and then posting
+// the allocations to any event notification callbacks.
//
-class JvmtiVMObjectAllocEventCollector : public JvmtiEventCollector {
- private:
- GrowableArray<oop>* _allocated; // field to record vm internally allocated object oop.
- bool _enable; // This flag is enabled in constructor and disabled
- // in destructor before posting event. To avoid
+class JvmtiObjectAllocEventCollector : public JvmtiEventCollector {
+ protected:
+ GrowableArray<oop>* _allocated; // field to record collected allocated object oop.
+ bool _enable; // This flag is enabled in constructor if set up in the thread state
+ // and disabled in destructor before posting event. To avoid
// collection of objects allocated while running java code inside
- // agent post_vm_object_alloc() event handler.
+ // agent post_X_object_alloc() event handler.
+ void (*_post_callback)(JavaThread*, oop); // what callback to use when destroying the collector.
//GC support
void oops_do(OopClosure* f);
friend class JvmtiExport;
- // Record vm allocated object oop.
+
+ // Record allocated object oop.
inline void record_allocation(oop obj);
//GC support
static void oops_do_for_all_threads(OopClosure* f);
public:
- JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN;
- ~JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN;
- bool is_vm_object_alloc_event() { return true; }
+ JvmtiObjectAllocEventCollector() NOT_JVMTI_RETURN;
+
+ void generate_call_for_allocated();
bool is_enabled() { return _enable; }
void set_enabled(bool on) { _enable = on; }
};
+// Used to record vm internally allocated object oops and post
+// vm object alloc event for objects visible to java world.
+// Constructor enables JvmtiThreadState flag and all vm allocated
+// objects are recorded in a growable array. When destructor is
+// called the vm object alloc event is posted for each object
+// visible to java world.
+// See jvm.cpp file for its usage.
+//
+class JvmtiVMObjectAllocEventCollector : public JvmtiObjectAllocEventCollector {
+ public:
+ JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN;
+ ~JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN;
+ virtual bool is_vm_object_alloc_event() { return true; }
+};
+// Used to record sampled allocated object oops and post
+// sampled object alloc event.
+// Constructor enables JvmtiThreadState flag and all sampled allocated
+// objects are recorded in a growable array. When destructor is
+// called the sampled object alloc event is posted for each sampled object.
+// See jvm.cpp file for its usage.
+//
+class JvmtiSampledObjectAllocEventCollector : public JvmtiObjectAllocEventCollector {
+ public:
+ JvmtiSampledObjectAllocEventCollector() NOT_JVMTI_RETURN;
+ ~JvmtiSampledObjectAllocEventCollector() NOT_JVMTI_RETURN;
+ bool is_sampled_object_alloc_event() { return true; }
+ static bool object_alloc_is_safe_to_sample();
+};
// Marker class to disable the posting of VMObjectAlloc events
// within its scope.