changeset 4359:d67b08a0b6c0

8007701: Hotspot trace allocation events Reviewed-by: brutisso, ehelin, egahlin
author neliasso
date Mon, 25 Mar 2013 14:03:21 +0100
parents 97f2e3ceb67c
children d44caacedf85
files src/share/vm/gc_interface/allocTracer.cpp src/share/vm/gc_interface/allocTracer.hpp src/share/vm/gc_interface/collectedHeap.cpp src/share/vm/gc_interface/collectedHeap.hpp src/share/vm/gc_interface/collectedHeap.inline.hpp src/share/vm/trace/trace.xml
diffstat 6 files changed, 121 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_interface/allocTracer.cpp	Mon Mar 25 14:03:21 2013 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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_interface/allocTracer.hpp"
+#include "trace/tracing.hpp"
+#include "runtime/handles.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+void AllocTracer::send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size) {
+  EventAllocObjectOutsideTLAB event;
+  if (event.should_commit()) {
+    event.set_class(klass());
+    event.set_allocationSize(alloc_size);
+    event.commit();
+  }
+}
+
+void AllocTracer::send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size) {
+  EventAllocObjectInNewTLAB event;
+  if (event.should_commit()) {
+    event.set_class(klass());
+    event.set_allocationSize(alloc_size);
+    event.set_tlabSize(tlab_size);
+    event.commit();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_interface/allocTracer.hpp	Mon Mar 25 14:03:21 2013 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, 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_INTERFACE_ALLOCTRACER_HPP
+#define SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/handles.hpp"
+
+class AllocTracer : AllStatic {
+  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);
+};
+
+#endif /* SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP */
--- a/src/share/vm/gc_interface/collectedHeap.cpp	Wed Apr 10 09:43:53 2013 +0200
+++ b/src/share/vm/gc_interface/collectedHeap.cpp	Mon Mar 25 14:03:21 2013 +0100
@@ -29,6 +29,7 @@
 #include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/gcWhen.hpp"
 #include "gc_implementation/shared/vmGCOperations.hpp"
+#include "gc_interface/allocTracer.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -218,7 +219,7 @@
 }
 #endif
 
-HeapWord* CollectedHeap::allocate_from_tlab_slow(Thread* thread, size_t size) {
+HeapWord* CollectedHeap::allocate_from_tlab_slow(KlassHandle klass, Thread* thread, size_t size) {
 
   // Retain tlab and allocate object in shared space if
   // the amount free in the tlab is too large to discard.
@@ -242,6 +243,9 @@
   if (obj == NULL) {
     return NULL;
   }
+
+  AllocTracer::send_allocation_in_new_tlab_event(klass, new_tlab_size * HeapWordSize, size * HeapWordSize);
+
   if (ZeroTLAB) {
     // ..and clear it.
     Copy::zero_to_words(obj, new_tlab_size);
@@ -528,7 +532,7 @@
     obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
   } else {
     assert(ScavengeRootsInCode > 0, "must be");
-    obj = common_mem_allocate_init(size, CHECK_NULL);
+    obj = common_mem_allocate_init(real_klass, size, CHECK_NULL);
   }
   post_allocation_setup_common(klass, obj);
   assert(Universe::is_bootstrapping() ||
--- a/src/share/vm/gc_interface/collectedHeap.hpp	Wed Apr 10 09:43:53 2013 +0200
+++ b/src/share/vm/gc_interface/collectedHeap.hpp	Mon Mar 25 14:03:21 2013 +0100
@@ -135,16 +135,16 @@
   virtual void resize_all_tlabs();
 
   // Allocate from the current thread's TLAB, with broken-out slow path.
-  inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size);
-  static HeapWord* allocate_from_tlab_slow(Thread* thread, size_t size);
+  inline static HeapWord* allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size);
+  static HeapWord* allocate_from_tlab_slow(KlassHandle klass, Thread* thread, size_t size);
 
   // Allocate an uninitialized block of the given size, or returns NULL if
   // this is impossible.
-  inline static HeapWord* common_mem_allocate_noinit(size_t size, TRAPS);
+  inline static HeapWord* common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS);
 
   // Like allocate_init, but the block returned by a successful allocation
   // is guaranteed initialized to zeros.
-  inline static HeapWord* common_mem_allocate_init(size_t size, TRAPS);
+  inline static HeapWord* common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS);
 
   // Same as common_mem version, except memory is allocated in the permanent area
   // If there is no permanent area, revert to common_mem_allocate_noinit
--- a/src/share/vm/gc_interface/collectedHeap.inline.hpp	Wed Apr 10 09:43:53 2013 +0200
+++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp	Mon Mar 25 14:03:21 2013 +0100
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
 #define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
 
+#include "gc_interface/allocTracer.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "memory/threadLocalAllocBuffer.inline.hpp"
 #include "memory/universe.hpp"
@@ -120,7 +121,7 @@
   post_allocation_notify(klass, (oop)obj);
 }
 
-HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) {
+HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS) {
 
   // Clear unhandled oops for memory allocation.  Memory allocation might
   // not take out a lock if from tlab, so clear here.
@@ -133,7 +134,7 @@
 
   HeapWord* result = NULL;
   if (UseTLAB) {
-    result = CollectedHeap::allocate_from_tlab(THREAD, size);
+    result = allocate_from_tlab(klass, THREAD, size);
     if (result != NULL) {
       assert(!HAS_PENDING_EXCEPTION,
              "Unexpected exception, will result in uninitialized storage");
@@ -149,6 +150,9 @@
     assert(!HAS_PENDING_EXCEPTION,
            "Unexpected exception, will result in uninitialized storage");
     THREAD->incr_allocated_bytes(size * HeapWordSize);
+
+    AllocTracer::send_allocation_outside_tlab_event(klass, size * HeapWordSize);
+
     return result;
   }
 
@@ -178,8 +182,8 @@
   }
 }
 
-HeapWord* CollectedHeap::common_mem_allocate_init(size_t size, TRAPS) {
-  HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
+HeapWord* CollectedHeap::common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS) {
+  HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
   init_obj(obj, size);
   return obj;
 }
@@ -227,7 +231,7 @@
   return obj;
 }
 
-HeapWord* CollectedHeap::allocate_from_tlab(Thread* thread, size_t size) {
+HeapWord* CollectedHeap::allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size) {
   assert(UseTLAB, "should use UseTLAB");
 
   HeapWord* obj = thread->tlab().allocate(size);
@@ -235,7 +239,7 @@
     return obj;
   }
   // Otherwise...
-  return allocate_from_tlab_slow(thread, size);
+  return allocate_from_tlab_slow(klass, thread, size);
 }
 
 void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
@@ -250,7 +254,7 @@
   debug_only(check_for_valid_allocation_state());
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
-  HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
+  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
   post_allocation_setup_obj(klass, obj);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
@@ -263,7 +267,7 @@
   debug_only(check_for_valid_allocation_state());
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
-  HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
+  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
   post_allocation_setup_array(klass, obj, length);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
@@ -276,7 +280,7 @@
   debug_only(check_for_valid_allocation_state());
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
-  HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
+  HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
   ((oop)obj)->set_klass_gap(0);
   post_allocation_setup_array(klass, obj, length);
 #ifndef PRODUCT
--- a/src/share/vm/trace/trace.xml	Wed Apr 10 09:43:53 2013 +0200
+++ b/src/share/vm/trace/trace.xml	Mon Mar 25 14:03:21 2013 +0100
@@ -296,7 +296,20 @@
       <value type="BOOLEAN" field="blocking" label="Caller Blocked" description="If the calling thread was blocked until the operation was complete."/>
       <value type="OSTHREAD" field="caller" label="Caller" transition="TO" description="Thread requesting operation. If non-blocking, will be set to 0 indicating thread is unknown."/>
     </event>
+    
+    <!-- Allocation events -->
+    <event id="AllocObjectInNewTLAB" path="java/object_alloc_in_new_TLAB" label="Allocation in new TLAB"
+        description="Allocation in new Thread Local Allocation Buffer" has_thread="true" has_stacktrace="true" is_instant="true">
+      <value type="CLASS" field="class" label="Class" description="Class of allocated object"/>
+      <value type="BYTES64" field="allocationSize" label="Allocation Size"/>
+      <value type="BYTES64" field="tlabSize" label="TLAB Size"/>
+    </event>
 
+    <event id="AllocObjectOutsideTLAB" path="java/object_alloc_outside_TLAB" label="Allocation outside TLAB"
+        description="Allocation outside Thread Local Allocation Buffers" has_thread="true" has_stacktrace="true" is_instant="true">
+      <value type="CLASS" field="class" label="Class" description="Class of allocated object"/>
+      <value type="BYTES64" field="allocationSize" label="Allocation Size"/>
+    </event>
   </events>
   
   <xi:include href="../../../closed/share/vm/trace/traceeventtypes.xml" xmlns:xi="http://www.w3.org/2001/XInclude">