src/hotspot/share/prims/jvmtiExport.hpp
changeset 50578 e2a7f431f65c
parent 49969 8624981f1ffa
child 52225 3c12f0c0a68c
--- 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.