36
36
#include " jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
37
37
#include " jfr/recorder/service/jfrOptionSet.hpp"
38
38
#include " jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
39
+ #include " jfr/recorder/storage/jfrReferenceCountedStorage.hpp"
39
40
#include " jfr/support/jfrKlassUnloading.hpp"
40
41
#include " jfr/support/jfrMethodLookup.hpp"
41
42
#include " jfr/utilities/jfrHashtable.hpp"
@@ -272,11 +273,30 @@ static void install_stack_traces(const ObjectSampler* sampler) {
272
273
iterate_samples (installer);
273
274
}
274
275
276
+ // Resets the blob write states from the previous epoch.
277
+ static void reset_blob_write_state (const ObjectSampler* sampler, JavaThread* jt) {
278
+ assert (sampler != nullptr , " invariant" );
279
+ const ObjectSample* sample = sampler->last_resolved ();
280
+ while (sample != nullptr ) {
281
+ if (sample->has_stacktrace ()) {
282
+ sample->stacktrace ()->reset_write_state ();
283
+ }
284
+ if (sample->has_thread ()) {
285
+ sample->thread ()->reset_write_state ();
286
+ }
287
+ if (sample->has_type_set ()) {
288
+ sample->type_set ()->reset_write_state ();
289
+ }
290
+ sample = sample->next ();
291
+ }
292
+ }
293
+
275
294
void ObjectSampleCheckpoint::on_rotation (const ObjectSampler* sampler) {
276
295
assert (sampler != nullptr , " invariant" );
277
296
assert (LeakProfiler::is_running (), " invariant" );
278
297
JavaThread* const thread = JavaThread::current ();
279
298
DEBUG_ONLY (JfrJavaSupport::check_java_thread_in_native (thread);)
299
+ reset_blob_write_state (sampler, thread);
280
300
if (!ObjectSampler::has_unresolved_entry ()) {
281
301
return ;
282
302
}
@@ -326,57 +346,49 @@ void ObjectSampleCheckpoint::write_stacktrace(const JfrStackTrace* trace, JfrChe
326
346
}
327
347
}
328
348
329
- static void write_blob (const JfrBlobHandle& blob, JfrCheckpointWriter& writer, bool reset) {
330
- if (reset) {
331
- blob->reset_write_state ();
332
- return ;
333
- }
349
+ static void write_blob (const JfrBlobHandle& blob, JfrCheckpointWriter& writer) {
334
350
blob->exclusive_write (writer);
335
351
}
336
352
337
- static void write_type_set_blob (const ObjectSample* sample, JfrCheckpointWriter& writer, bool reset ) {
353
+ static void write_type_set_blob (const ObjectSample* sample, JfrCheckpointWriter& writer) {
338
354
if (sample->has_type_set ()) {
339
- write_blob (sample->type_set (), writer, reset );
355
+ write_blob (sample->type_set (), writer);
340
356
}
341
357
}
342
358
343
- static void write_thread_blob (const ObjectSample* sample, JfrCheckpointWriter& writer, bool reset ) {
359
+ static void write_thread_blob (const ObjectSample* sample, JfrCheckpointWriter& writer) {
344
360
assert (sample->has_thread (), " invariant" );
345
361
if (sample->is_virtual_thread () || has_thread_exited (sample->thread_id ())) {
346
- write_blob (sample->thread (), writer, reset );
362
+ write_blob (sample->thread (), writer);
347
363
}
348
364
}
349
365
350
- static void write_stacktrace_blob (const ObjectSample* sample, JfrCheckpointWriter& writer, bool reset ) {
366
+ static void write_stacktrace_blob (const ObjectSample* sample, JfrCheckpointWriter& writer) {
351
367
if (sample->has_stacktrace ()) {
352
- write_blob (sample->stacktrace (), writer, reset );
368
+ write_blob (sample->stacktrace (), writer);
353
369
}
354
370
}
355
371
356
- static void write_blobs (const ObjectSample* sample, JfrCheckpointWriter& writer, bool reset ) {
372
+ static void write_blobs (const ObjectSample* sample, JfrCheckpointWriter& writer) {
357
373
assert (sample != nullptr , " invariant" );
358
- write_stacktrace_blob (sample, writer, reset );
359
- write_thread_blob (sample, writer, reset );
360
- write_type_set_blob (sample, writer, reset );
374
+ write_stacktrace_blob (sample, writer);
375
+ write_thread_blob (sample, writer);
376
+ write_type_set_blob (sample, writer);
361
377
}
362
378
363
379
class BlobWriter {
364
380
private:
365
381
const ObjectSampler* _sampler;
366
382
JfrCheckpointWriter& _writer;
367
383
const jlong _last_sweep;
368
- bool _reset;
369
384
public:
370
385
BlobWriter (const ObjectSampler* sampler, JfrCheckpointWriter& writer, jlong last_sweep) :
371
- _sampler (sampler), _writer(writer), _last_sweep(last_sweep), _reset( false ) {}
386
+ _sampler (sampler), _writer(writer), _last_sweep(last_sweep) {}
372
387
void sample_do (ObjectSample* sample) {
373
388
if (sample->is_alive_and_older_than (_last_sweep)) {
374
- write_blobs (sample, _writer, _reset );
389
+ write_blobs (sample, _writer);
375
390
}
376
391
}
377
- void set_reset () {
378
- _reset = true ;
379
- }
380
392
};
381
393
382
394
static void write_sample_blobs (const ObjectSampler* sampler, bool emit_all, Thread* thread) {
@@ -385,9 +397,6 @@ static void write_sample_blobs(const ObjectSampler* sampler, bool emit_all, Thre
385
397
JfrCheckpointWriter writer (thread, false );
386
398
BlobWriter cbw (sampler, writer, last_sweep);
387
399
iterate_samples (cbw, true );
388
- // reset blob write states
389
- cbw.set_reset ();
390
- iterate_samples (cbw, true );
391
400
}
392
401
393
402
void ObjectSampleCheckpoint::write (const ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) {
@@ -403,67 +412,17 @@ void ObjectSampleCheckpoint::write(const ObjectSampler* sampler, EdgeStore* edge
403
412
}
404
413
}
405
414
406
- // A linked list of saved type set blobs for the epoch.
407
- // The link consist of a reference counted handle.
408
- static JfrBlobHandle saved_type_set_blobs;
409
-
410
- static void release_state_for_previous_epoch () {
411
- // decrements the reference count and the list is reinitialized
412
- saved_type_set_blobs = JfrBlobHandle ();
413
- }
414
-
415
- class BlobInstaller {
416
- public:
417
- ~BlobInstaller () {
418
- release_state_for_previous_epoch ();
419
- }
420
- void sample_do (ObjectSample* sample) {
421
- if (!sample->is_dead ()) {
422
- sample->set_type_set (saved_type_set_blobs);
423
- }
424
- }
425
- };
426
-
427
- static void install_type_set_blobs () {
428
- if (saved_type_set_blobs.valid ()) {
429
- BlobInstaller installer;
430
- iterate_samples (installer);
431
- }
432
- }
433
-
434
- static void save_type_set_blob (JfrCheckpointWriter& writer) {
435
- assert (writer.has_data (), " invariant" );
436
- const JfrBlobHandle blob = writer.copy ();
437
- if (saved_type_set_blobs.valid ()) {
438
- saved_type_set_blobs->set_next (blob);
439
- } else {
440
- saved_type_set_blobs = blob;
441
- }
442
- }
443
-
444
415
// This routine has exclusive access to the sampler instance on entry.
445
- void ObjectSampleCheckpoint::on_type_set (JfrCheckpointWriter& writer ) {
416
+ void ObjectSampleCheckpoint::on_type_set (JavaThread* jt ) {
446
417
assert (LeakProfiler::is_running (), " invariant" );
447
418
DEBUG_ONLY (JfrJavaSupport::check_java_thread_in_vm (JavaThread::current ());)
448
419
assert (ClassLoaderDataGraph_lock->owned_by_self (), " invariant" );
449
420
if (!ObjectSampler::has_unresolved_entry ()) {
450
421
return ;
451
422
}
452
- const ObjectSample* const last = ObjectSampler::sampler ()->last ();
423
+ ObjectSample* const last = ObjectSampler::sampler ()->last ();
453
424
assert (last != nullptr , " invariant" );
454
425
assert (last != ObjectSampler::sampler ()->last_resolved (), " invariant" );
455
- if (writer.has_data ()) {
456
- save_type_set_blob (writer);
457
- }
458
- install_type_set_blobs ();
426
+ JfrReferenceCountedStorage::install (last, ObjectSampler::sampler ()->last_resolved ());
459
427
ObjectSampler::sampler ()->set_last_resolved (last);
460
428
}
461
-
462
- // This routine does NOT have exclusive access to the sampler instance on entry.
463
- void ObjectSampleCheckpoint::on_type_set_unload (JfrCheckpointWriter& writer) {
464
- assert (LeakProfiler::is_running (), " invariant" );
465
- assert_locked_or_safepoint (ClassLoaderDataGraph_lock);
466
- if (writer.has_data () && ObjectSampler::has_unresolved_entry ()) {
467
- save_type_set_blob (writer);
468
- }
469
- }
0 commit comments