@@ -51,7 +51,6 @@ class MemAllocator::Allocation: StackObj {
5151 bool _overhead_limit_exceeded;
5252 bool _allocated_outside_tlab;
5353 size_t _allocated_tlab_size;
54- bool _tlab_end_reset_for_sample;
5554
5655 bool check_out_of_memory ();
5756 void verify_before ();
@@ -74,8 +73,7 @@ class MemAllocator::Allocation: StackObj {
7473 _obj_ptr(obj_ptr),
7574 _overhead_limit_exceeded(false ),
7675 _allocated_outside_tlab(false ),
77- _allocated_tlab_size(0 ),
78- _tlab_end_reset_for_sample(false )
76+ _allocated_tlab_size(0 )
7977 {
8078 assert (Thread::current () == allocator._thread , " do not pass MemAllocator across threads" );
8179 verify_before ();
@@ -174,33 +172,31 @@ void MemAllocator::Allocation::notify_allocation_jvmti_sampler() {
174172 return ;
175173 }
176174
177- if (!_allocated_outside_tlab && _allocated_tlab_size == 0 && !_tlab_end_reset_for_sample) {
178- // Sample if it's a non-TLAB allocation, or a TLAB allocation that either refills the TLAB
179- // or expands it due to taking a sampler induced slow path.
180- return ;
181- }
175+ ThreadHeapSampler& heap_sampler = _thread->heap_sampler ();
176+ ThreadLocalAllocBuffer& tlab = _thread->tlab ();
182177
183- // If we want to be sampling, protect the allocated object with a Handle
184- // before doing the callback. The callback is done in the destructor of
185- // the JvmtiSampledObjectAllocEventCollector.
186- size_t bytes_since_last = 0 ;
178+ // Log sample decision
179+ heap_sampler.log_sample_decision (tlab.top ());
187180
188- {
181+ if (heap_sampler.should_sample (tlab.top ())) {
182+ // If we want to be sampling, protect the allocated object with a Handle
183+ // before doing the callback. The callback is done in the destructor of
184+ // the JvmtiSampledObjectAllocEventCollector.
189185 PreserveObj obj_h (_thread, _obj_ptr);
190186 JvmtiSampledObjectAllocEventCollector collector;
191- size_t size_in_bytes = _allocator._word_size * HeapWordSize;
192- ThreadLocalAllocBuffer& tlab = _thread->tlab ();
193187
194- if (!_allocated_outside_tlab) {
195- bytes_since_last = tlab.bytes_since_last_sample_point ();
196- }
188+ // Perform the sampling
189+ heap_sampler.sample (obj_h (), tlab.top ());
197190
198- _thread->heap_sampler ().check_for_sampling (obj_h (), size_in_bytes, bytes_since_last);
191+ // Note that after this point all the TLAB can have been retired, and agent
192+ // code can run and allocate, don't rely on earlier calculations involving
193+ // the TLAB.
199194 }
200195
201- if (_tlab_end_reset_for_sample || _allocated_tlab_size != 0 ) {
202- // Tell tlab to forget bytes_since_last if we passed it to the heap sampler.
203- _thread->tlab ().set_sample_end (bytes_since_last != 0 );
196+ // Set a new sampling point in the TLAB if it fits in the current TLAB
197+ const size_t words_until_sample = heap_sampler.bytes_until_sample (tlab.top ()) / HeapWordSize;
198+ if (words_until_sample <= tlab.free ()) {
199+ tlab.set_sampling_point (tlab.top () + words_until_sample);
204200 }
205201}
206202
@@ -249,6 +245,7 @@ HeapWord* MemAllocator::mem_allocate_outside_tlab(Allocation& allocation) const
249245
250246 size_t size_in_bytes = _word_size * HeapWordSize;
251247 _thread->incr_allocated_bytes (size_in_bytes);
248+ _thread->heap_sampler ().inc_outside_tlab_bytes (size_in_bytes);
252249
253250 return mem;
254251}
@@ -262,12 +259,16 @@ HeapWord* MemAllocator::mem_allocate_inside_tlab_slow(Allocation& allocation) co
262259 ThreadLocalAllocBuffer& tlab = _thread->tlab ();
263260
264261 if (JvmtiExport::should_post_sampled_object_alloc ()) {
262+ // When sampling we artificially set the TLAB end to the sample point.
263+ // When we hit that point it looks like the TLAB is full, but it's
264+ // not necessarily the case. Set the real end and retry the allocation.
265+
266+ // Undo previous adjustment of end.
267+ // Note that notify_allocation_jvmti_sampler will set a new sample point.
265268 tlab.set_back_allocation_end ();
266- mem = tlab.allocate (_word_size);
267269
268- // We set back the allocation sample point to try to allocate this, reset it
269- // when done.
270- allocation._tlab_end_reset_for_sample = true ;
270+ // Retry the TLAB allocation with the proper end
271+ mem = tlab.allocate (_word_size);
271272
272273 if (mem != nullptr ) {
273274 return mem;
@@ -282,11 +283,16 @@ HeapWord* MemAllocator::mem_allocate_inside_tlab_slow(Allocation& allocation) co
282283 }
283284
284285 // Discard tlab and allocate a new one.
286+
287+ // Record the amount wasted
288+ tlab.record_refill_waste ();
289+
290+ // Retire the current TLAB
291+ _thread->retire_tlab ();
292+
285293 // To minimize fragmentation, the last TLAB may be smaller than the rest.
286294 size_t new_tlab_size = tlab.compute_size (_word_size);
287295
288- tlab.retire_before_allocation ();
289-
290296 if (new_tlab_size == 0 ) {
291297 return nullptr ;
292298 }
@@ -317,7 +323,8 @@ HeapWord* MemAllocator::mem_allocate_inside_tlab_slow(Allocation& allocation) co
317323 Copy::fill_to_words (mem + hdr_size, allocation._allocated_tlab_size - hdr_size, badHeapWordVal);
318324 }
319325
320- tlab.fill (mem, mem + _word_size, allocation._allocated_tlab_size );
326+ _thread->fill_tlab (mem, _word_size, allocation._allocated_tlab_size );
327+
321328 return mem;
322329}
323330
0 commit comments