3030#include " gc/shared/memAllocator.hpp"
3131#include " gc/shared/threadLocalAllocBuffer.inline.hpp"
3232#include " gc/shared/tlab_globals.hpp"
33+ #include " jfr/jfrEvents.hpp"
3334#include " memory/universe.hpp"
3435#include " oops/arrayOop.hpp"
3536#include " oops/oop.inline.hpp"
4142#include " services/lowMemoryDetector.hpp"
4243#include " utilities/align.hpp"
4344#include " utilities/copy.hpp"
45+ #include " utilities/dtrace.hpp"
4446#include " utilities/globalDefinitions.hpp"
4547
4648class MemAllocator ::Allocation: StackObj {
@@ -52,7 +54,8 @@ class MemAllocator::Allocation: StackObj {
5254 bool _overhead_limit_exceeded;
5355 bool _allocated_outside_tlab;
5456 size_t _allocated_tlab_size;
55- bool _tlab_end_reset_for_sample;
57+ bool _tlab_end_reset_for_jvmti_sample;
58+ bool _tlab_end_reset_for_jfr_sample;
5659
5760 bool check_out_of_memory ();
5861 void verify_before ();
@@ -76,7 +79,8 @@ class MemAllocator::Allocation: StackObj {
7679 _overhead_limit_exceeded(false ),
7780 _allocated_outside_tlab(false ),
7881 _allocated_tlab_size(0 ),
79- _tlab_end_reset_for_sample(false )
82+ _tlab_end_reset_for_jvmti_sample(false ),
83+ _tlab_end_reset_for_jfr_sample(false )
8084 {
8185 assert (Thread::current () == allocator._thread , " do not pass MemAllocator across threads" );
8286 verify_before ();
@@ -171,7 +175,7 @@ void MemAllocator::Allocation::notify_allocation_jvmti_sampler() {
171175 return ;
172176 }
173177
174- if (!_allocated_outside_tlab && _allocated_tlab_size == 0 && !_tlab_end_reset_for_sample ) {
178+ if (!_allocated_outside_tlab && _allocated_tlab_size == 0 && !_tlab_end_reset_for_jvmti_sample ) {
175179 // Sample if it's a non-TLAB allocation, or a TLAB allocation that either refills the TLAB
176180 // or expands it due to taking a sampler induced slow path.
177181 return ;
@@ -181,23 +185,21 @@ void MemAllocator::Allocation::notify_allocation_jvmti_sampler() {
181185 // before doing the callback. The callback is done in the destructor of
182186 // the JvmtiSampledObjectAllocEventCollector.
183187 size_t bytes_since_last = 0 ;
184-
188+ size_t bytes_since_allocation = 0 ;
185189 {
186190 PreserveObj obj_h (_thread, _obj_ptr);
187191 JvmtiSampledObjectAllocEventCollector collector;
188192 size_t size_in_bytes = _allocator._word_size * HeapWordSize;
189- ThreadLocalAllocBuffer& tlab = _thread->tlab ();
190193
191- if (!_allocated_outside_tlab) {
192- bytes_since_last = tlab.bytes_since_last_sample_point ();
194+ if (_thread->heap_samplers ().jvmti ().check_for_sampling (&bytes_since_allocation, size_in_bytes, !_allocated_outside_tlab)) {
195+ // HOTSPOT_GC_ALLOCOBJECT_SAMPLE(obj_h->klass()->name()->as_C_string(), size_in_bytes, bytes_since_allocation);
196+ JvmtiExport::sampled_object_alloc_event_collector (obj_h ());
193197 }
194-
195- _thread->heap_sampler ().check_for_sampling (obj_h (), size_in_bytes, bytes_since_last);
196198 }
197199
198- if (_tlab_end_reset_for_sample || _allocated_tlab_size != 0 ) {
200+ if (_tlab_end_reset_for_jvmti_sample || _allocated_tlab_size != 0 ) {
199201 // Tell tlab to forget bytes_since_last if we passed it to the heap sampler.
200- _thread->tlab ().set_sample_end (bytes_since_last != 0 );
202+ _thread->tlab ().set_jvmti_sample_end (!_allocated_outside_tlab );
201203 }
202204}
203205
@@ -217,6 +219,30 @@ void MemAllocator::Allocation::notify_allocation_jfr_sampler() {
217219 AllocTracer::send_allocation_in_new_tlab (obj ()->klass (), mem, _allocated_tlab_size * HeapWordSize,
218220 size_in_bytes, _thread);
219221 }
222+
223+ EventObjectAllocationSample event;
224+ if (!event.should_commit ()) {
225+ return ;
226+ }
227+
228+ bool hit_mark = _allocated_tlab_size != 0 || _tlab_end_reset_for_jfr_sample;
229+ if (!_allocated_outside_tlab && !hit_mark) {
230+ // Sample if it's a non-TLAB allocation, or a TLAB allocation that either refills the TLAB
231+ // or expands it due to taking a sampler induced slow path.
232+ return ;
233+ }
234+
235+ size_t bytes_since_allocation = 0 ;
236+ if (_thread->heap_samplers ().jfr ().check_for_sampling (&bytes_since_allocation, size_in_bytes, !_allocated_outside_tlab)) {
237+ size_t weight = bytes_since_allocation == 0 ? size_in_bytes : bytes_since_allocation;
238+ AllocTracer::send_allocation_sample (obj ()->klass (), mem, size_in_bytes, weight, _allocated_outside_tlab, _thread);
239+ HOTSPOT_GC_ALLOCOBJECT_SAMPLE (obj ()->klass ()->name ()->as_C_string (), size_in_bytes, weight);
240+ }
241+
242+ if (hit_mark) {
243+ // Tell tlab to forget bytes_since_last if we passed it to the heap sampler.
244+ _thread->tlab ().set_jfr_sample_end (!_allocated_outside_tlab);
245+ }
220246}
221247
222248void MemAllocator::Allocation::notify_allocation_dtrace_sampler () {
@@ -264,7 +290,7 @@ HeapWord* MemAllocator::mem_allocate_inside_tlab_slow(Allocation& allocation) co
264290
265291 // We set back the allocation sample point to try to allocate this, reset it
266292 // when done.
267- allocation._tlab_end_reset_for_sample = true ;
293+ allocation._tlab_end_reset_for_jvmti_sample = true ;
268294
269295 if (mem != nullptr ) {
270296 return mem;
0 commit comments