Skip to content

Commit a8ea3c2

Browse files
Dmitry ChuykoPaul Hohensee
authored andcommitted
8288663: JFR: Disabling the JfrThreadSampler commits only a partially disabled state
Reviewed-by: phh Backport-of: a7df5a40639a4d3138616c9fc1b144381240d2e5
1 parent 8bf03b9 commit a8ea3c2

File tree

7 files changed

+103
-74
lines changed

7 files changed

+103
-74
lines changed

src/hotspot/share/jfr/jni/jfrJniMethod.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,19 +270,19 @@ JVM_ENTRY_NO_ENV(void, jfr_set_output(JNIEnv* env, jobject jvm, jstring path))
270270
JfrRepository::set_chunk_path(path, thread);
271271
JVM_END
272272

273-
JVM_ENTRY_NO_ENV(void, jfr_set_method_sampling_interval(JNIEnv* env, jobject jvm, jlong type, jlong intervalMillis))
274-
if (intervalMillis < 0) {
275-
intervalMillis = 0;
273+
JVM_ENTRY_NO_ENV(void, jfr_set_method_sampling_period(JNIEnv* env, jobject jvm, jlong type, jlong periodMillis))
274+
if (periodMillis < 0) {
275+
periodMillis = 0;
276276
}
277277
JfrEventId typed_event_id = (JfrEventId)type;
278278
assert(EventExecutionSample::eventId == typed_event_id || EventNativeMethodSample::eventId == typed_event_id, "invariant");
279-
if (intervalMillis > 0) {
279+
if (periodMillis > 0) {
280280
JfrEventSetting::set_enabled(typed_event_id, true); // ensure sampling event is enabled
281281
}
282282
if (EventExecutionSample::eventId == type) {
283-
JfrThreadSampling::set_java_sample_interval(intervalMillis);
283+
JfrThreadSampling::set_java_sample_period(periodMillis);
284284
} else {
285-
JfrThreadSampling::set_native_sample_interval(intervalMillis);
285+
JfrThreadSampling::set_native_sample_period(periodMillis);
286286
}
287287
JVM_END
288288

src/hotspot/share/jfr/jni/jfrJniMethod.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void JNICALL jfr_set_global_buffer_count(JNIEnv* env, jobject jvm, jlong count);
8383

8484
void JNICALL jfr_set_global_buffer_size(JNIEnv* env, jobject jvm, jlong size);
8585

86-
void JNICALL jfr_set_method_sampling_interval(JNIEnv* env, jobject jvm, jlong type, jlong intervalMillis);
86+
void JNICALL jfr_set_method_sampling_period(JNIEnv* env, jobject jvm, jlong type, jlong periodMillis);
8787

8888
void JNICALL jfr_set_output(JNIEnv* env, jobject jvm, jstring path);
8989

src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) {
5757
(char*)"setFileNotification", (char*)"(J)V", (void*)jfr_set_file_notification,
5858
(char*)"setGlobalBufferCount", (char*)"(J)V", (void*)jfr_set_global_buffer_count,
5959
(char*)"setGlobalBufferSize", (char*)"(J)V", (void*)jfr_set_global_buffer_size,
60-
(char*)"setMethodSamplingInterval", (char*)"(JJ)V", (void*)jfr_set_method_sampling_interval,
60+
(char*)"setMethodSamplingPeriod", (char*)"(JJ)V", (void*)jfr_set_method_sampling_period,
6161
(char*)"setOutput", (char*)"(Ljava/lang/String;)V", (void*)jfr_set_output,
6262
(char*)"setSampleThreads", (char*)"(Z)V", (void*)jfr_set_sample_threads,
6363
(char*)"setStackDepth", (char*)"(I)V", (void*)jfr_set_stack_depth,

src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp

Lines changed: 83 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -321,25 +321,23 @@ class JfrThreadSampler : public NonJavaThread {
321321
JfrStackFrame* const _frames;
322322
JavaThread* _last_thread_java;
323323
JavaThread* _last_thread_native;
324-
size_t _interval_java;
325-
size_t _interval_native;
324+
int64_t _java_period_millis;
325+
int64_t _native_period_millis;
326326
int _cur_index;
327327
const u4 _max_frames;
328328
volatile bool _disenrolled;
329329

330330
JavaThread* next_thread(ThreadsList* t_list, JavaThread* first_sampled, JavaThread* current);
331331
void task_stacktrace(JfrSampleType type, JavaThread** last_thread);
332-
JfrThreadSampler(size_t interval_java, size_t interval_native, u4 max_frames);
332+
JfrThreadSampler(int64_t java_period_millis, int64_t native_period_millis, u4 max_frames);
333333
~JfrThreadSampler();
334334

335335
void start_thread();
336336

337337
void enroll();
338338
void disenroll();
339-
void set_java_interval(size_t interval) { _interval_java = interval; };
340-
void set_native_interval(size_t interval) { _interval_native = interval; };
341-
size_t get_java_interval() { return _interval_java; };
342-
size_t get_native_interval() { return _interval_native; };
339+
void set_java_period(int64_t period_millis);
340+
void set_native_period(int64_t period_millis);
343341
protected:
344342
virtual void post_run();
345343
public:
@@ -348,6 +346,8 @@ class JfrThreadSampler : public NonJavaThread {
348346
void run();
349347
static Monitor* transition_block() { return JfrThreadSampler_lock; }
350348
static void on_javathread_suspend(JavaThread* thread);
349+
int64_t get_java_period() const { return _java_period_millis; };
350+
int64_t get_native_period() const { return _native_period_millis; };
351351
};
352352

353353
static void clear_transition_block(JavaThread* jt) {
@@ -387,23 +387,35 @@ bool JfrThreadSampleClosure::do_sample_thread(JavaThread* thread, JfrStackFrame*
387387
return ret;
388388
}
389389

390-
JfrThreadSampler::JfrThreadSampler(size_t interval_java, size_t interval_native, u4 max_frames) :
390+
JfrThreadSampler::JfrThreadSampler(int64_t java_period_millis, int64_t native_period_millis, u4 max_frames) :
391391
_sample(),
392392
_sampler_thread(NULL),
393393
_frames(JfrCHeapObj::new_array<JfrStackFrame>(max_frames)),
394394
_last_thread_java(NULL),
395395
_last_thread_native(NULL),
396-
_interval_java(interval_java),
397-
_interval_native(interval_native),
396+
_java_period_millis(java_period_millis),
397+
_native_period_millis(native_period_millis),
398398
_cur_index(-1),
399399
_max_frames(max_frames),
400400
_disenrolled(true) {
401+
assert(_java_period_millis >= 0, "invariant");
402+
assert(_native_period_millis >= 0, "invariant");
401403
}
402404

403405
JfrThreadSampler::~JfrThreadSampler() {
404406
JfrCHeapObj::free(_frames, sizeof(JfrStackFrame) * _max_frames);
405407
}
406408

409+
void JfrThreadSampler::set_java_period(int64_t period_millis) {
410+
assert(period_millis >= 0, "invariant");
411+
_java_period_millis = period_millis;
412+
}
413+
414+
void JfrThreadSampler::set_native_period(int64_t period_millis) {
415+
assert(period_millis >= 0, "invariant");
416+
_native_period_millis = period_millis;
417+
}
418+
407419
static inline bool is_released(JavaThread* jt) {
408420
return !jt->is_trace_suspend();
409421
}
@@ -461,7 +473,7 @@ void JfrThreadSampler::disenroll() {
461473
}
462474
}
463475

464-
static jlong get_monotonic_ms() {
476+
static int64_t get_monotonic_ms() {
465477
return os::javaTimeNanos() / 1000000;
466478
}
467479

@@ -470,8 +482,8 @@ void JfrThreadSampler::run() {
470482

471483
_sampler_thread = this;
472484

473-
jlong last_java_ms = get_monotonic_ms();
474-
jlong last_native_ms = last_java_ms;
485+
int64_t last_java_ms = get_monotonic_ms();
486+
int64_t last_native_ms = last_java_ms;
475487
while (true) {
476488
if (!_sample.trywait()) {
477489
// disenrolled
@@ -480,24 +492,24 @@ void JfrThreadSampler::run() {
480492
last_native_ms = last_java_ms;
481493
}
482494
_sample.signal();
483-
jlong java_interval = _interval_java == 0 ? max_jlong : MAX2<jlong>(_interval_java, 1);
484-
jlong native_interval = _interval_native == 0 ? max_jlong : MAX2<jlong>(_interval_native, 1);
495+
const int64_t java_period_millis = _java_period_millis == 0 ? max_jlong : MAX2<int64_t>(_java_period_millis, 1);
496+
const int64_t native_period_millis = _native_period_millis == 0 ? max_jlong : MAX2<int64_t>(_native_period_millis, 1);
485497

486-
jlong now_ms = get_monotonic_ms();
498+
const int64_t now_ms = get_monotonic_ms();
487499

488500
/*
489-
* Let I be java_interval or native_interval.
501+
* Let I be java_period or native_period.
490502
* Let L be last_java_ms or last_native_ms.
491503
* Let N be now_ms.
492504
*
493505
* Interval, I, might be max_jlong so the addition
494506
* could potentially overflow without parenthesis (UB). Also note that
495507
* L - N < 0. Avoid UB, by adding parenthesis.
496508
*/
497-
jlong next_j = java_interval + (last_java_ms - now_ms);
498-
jlong next_n = native_interval + (last_native_ms - now_ms);
509+
const int64_t next_j = java_period_millis + (last_java_ms - now_ms);
510+
const int64_t next_n = native_period_millis + (last_native_ms - now_ms);
499511

500-
jlong sleep_to_next = MIN2<jlong>(next_j, next_n);
512+
const int64_t sleep_to_next = MIN2<int64_t>(next_j, next_n);
501513

502514
if (sleep_to_next > 0) {
503515
os::naked_short_sleep(sleep_to_next);
@@ -594,58 +606,76 @@ JfrThreadSampling::~JfrThreadSampling() {
594606
}
595607
}
596608

597-
static void log(size_t interval_java, size_t interval_native) {
598-
log_trace(jfr)("Updated thread sampler for java: " SIZE_FORMAT " ms, native " SIZE_FORMAT " ms", interval_java, interval_native);
609+
#ifdef ASSERT
610+
void assert_periods(const JfrThreadSampler* sampler, int64_t java_period_millis, int64_t native_period_millis) {
611+
assert(sampler != nullptr, "invariant");
612+
assert(sampler->get_java_period() == java_period_millis, "invariant");
613+
assert(sampler->get_native_period() == native_period_millis, "invariant");
614+
}
615+
#endif
616+
617+
static void log(int64_t java_period_millis, int64_t native_period_millis) {
618+
log_trace(jfr)("Updated thread sampler for java: " INT64_FORMAT " ms, native " INT64_FORMAT " ms", java_period_millis, native_period_millis);
599619
}
600620

601-
void JfrThreadSampling::start_sampler(size_t interval_java, size_t interval_native) {
602-
assert(_sampler == NULL, "invariant");
603-
log_trace(jfr)("Enrolling thread sampler");
604-
_sampler = new JfrThreadSampler(interval_java, interval_native, JfrOptionSet::stackdepth());
621+
void JfrThreadSampling::create_sampler(int64_t java_period_millis, int64_t native_period_millis) {
622+
assert(_sampler == nullptr, "invariant");
623+
log_trace(jfr)("Creating thread sampler for java:" INT64_FORMAT " ms, native " INT64_FORMAT " ms", java_period_millis, native_period_millis);
624+
_sampler = new JfrThreadSampler(java_period_millis, native_period_millis, JfrOptionSet::stackdepth());
605625
_sampler->start_thread();
606626
_sampler->enroll();
607627
}
608628

609-
void JfrThreadSampling::set_sampling_interval(bool java_interval, size_t period) {
610-
size_t interval_java = 0;
611-
size_t interval_native = 0;
612-
if (_sampler != NULL) {
613-
interval_java = _sampler->get_java_interval();
614-
interval_native = _sampler->get_native_interval();
615-
}
616-
if (java_interval) {
617-
interval_java = period;
618-
} else {
619-
interval_native = period;
620-
}
621-
if (interval_java > 0 || interval_native > 0) {
622-
if (_sampler == NULL) {
623-
log_trace(jfr)("Creating thread sampler for java:%zu ms, native %zu ms", interval_java, interval_native);
624-
start_sampler(interval_java, interval_native);
629+
void JfrThreadSampling::update_run_state(int64_t java_period_millis, int64_t native_period_millis) {
630+
if (java_period_millis > 0 || native_period_millis > 0) {
631+
if (_sampler == nullptr) {
632+
create_sampler(java_period_millis, native_period_millis);
625633
} else {
626-
_sampler->set_java_interval(interval_java);
627-
_sampler->set_native_interval(interval_native);
628634
_sampler->enroll();
629635
}
630-
assert(_sampler != NULL, "invariant");
631-
log(interval_java, interval_native);
632-
} else if (_sampler != NULL) {
636+
DEBUG_ONLY(assert_periods(_sampler, java_period_millis, native_period_millis);)
637+
log(java_period_millis, native_period_millis);
638+
return;
639+
}
640+
if (_sampler != nullptr) {
641+
DEBUG_ONLY(assert_periods(_sampler, java_period_millis, native_period_millis);)
633642
_sampler->disenroll();
634643
}
635644
}
636645

637-
void JfrThreadSampling::set_java_sample_interval(size_t period) {
638-
if (_instance == NULL && 0 == period) {
646+
void JfrThreadSampling::set_sampling_period(bool is_java_period, int64_t period_millis) {
647+
int64_t java_period_millis = 0;
648+
int64_t native_period_millis = 0;
649+
if (is_java_period) {
650+
java_period_millis = period_millis;
651+
if (_sampler != nullptr) {
652+
_sampler->set_java_period(java_period_millis);
653+
native_period_millis = _sampler->get_native_period();
654+
}
655+
} else {
656+
native_period_millis = period_millis;
657+
if (_sampler != nullptr) {
658+
_sampler->set_native_period(native_period_millis);
659+
java_period_millis = _sampler->get_java_period();
660+
}
661+
}
662+
update_run_state(java_period_millis, native_period_millis);
663+
}
664+
665+
void JfrThreadSampling::set_java_sample_period(int64_t period_millis) {
666+
assert(period_millis >= 0, "invariant");
667+
if (_instance == NULL && 0 == period_millis) {
639668
return;
640669
}
641-
instance().set_sampling_interval(true, period);
670+
instance().set_sampling_period(true, period_millis);
642671
}
643672

644-
void JfrThreadSampling::set_native_sample_interval(size_t period) {
645-
if (_instance == NULL && 0 == period) {
673+
void JfrThreadSampling::set_native_sample_period(int64_t period_millis) {
674+
assert(period_millis >= 0, "invariant");
675+
if (_instance == NULL && 0 == period_millis) {
646676
return;
647677
}
648-
instance().set_sampling_interval(false, period);
678+
instance().set_sampling_period(false, period_millis);
649679
}
650680

651681
void JfrThreadSampling::on_javathread_suspend(JavaThread* thread) {

src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -28,16 +28,15 @@
2828
#include "jfr/utilities/jfrAllocation.hpp"
2929

3030
class JavaThread;
31-
class JfrStackFrame;
3231
class JfrThreadSampler;
33-
class Thread;
3432

3533
class JfrThreadSampling : public JfrCHeapObj {
3634
friend class JfrRecorder;
3735
private:
3836
JfrThreadSampler* _sampler;
39-
void start_sampler(size_t interval_java, size_t interval_native);
40-
void set_sampling_interval(bool java_interval, size_t period);
37+
void create_sampler(int64_t java_period_millis, int64_t native_period_millis);
38+
void update_run_state(int64_t java_period_millis, int64_t native_period_millis);
39+
void set_sampling_period(bool is_java_period, int64_t period_millis);
4140

4241
JfrThreadSampling();
4342
~JfrThreadSampling();
@@ -47,8 +46,8 @@ class JfrThreadSampling : public JfrCHeapObj {
4746
static void destroy();
4847

4948
public:
50-
static void set_java_sample_interval(size_t period);
51-
static void set_native_sample_interval(size_t period);
49+
static void set_java_sample_period(int64_t period_millis);
50+
static void set_native_sample_period(int64_t period_millis);
5251
static void on_javathread_suspend(JavaThread* thread);
5352
};
5453

src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,13 @@ private JVM() {
266266
public native void setMemorySize(long size) throws IllegalArgumentException;
267267

268268
/**
269-
* Set interval for method samples, in milliseconds.
269+
* Set period for method samples, in milliseconds.
270270
*
271-
* Setting interval to 0 turns off the method sampler.
271+
* Setting period to 0 turns off the method sampler.
272272
*
273-
* @param intervalMillis the sampling interval
273+
* @param periodMillis the sampling period
274274
*/
275-
public native void setMethodSamplingInterval(long type, long intervalMillis);
275+
public native void setMethodSamplingPeriod(long type, long periodMillis);
276276

277277
/**
278278
* Sets the file where data should be written.

src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ public void setEnabled(boolean enabled) {
206206
if (isJVM) {
207207
if (isMethodSampling) {
208208
long p = enabled ? period : 0;
209-
JVM.getJVM().setMethodSamplingInterval(getId(), p);
209+
JVM.getJVM().setMethodSamplingPeriod(getId(), p);
210210
} else {
211211
JVM.getJVM().setEnabled(getId(), enabled);
212212
}
@@ -216,7 +216,7 @@ public void setEnabled(boolean enabled) {
216216
public void setPeriod(long periodMillis, boolean beginChunk, boolean endChunk) {
217217
if (isMethodSampling) {
218218
long p = enabled ? periodMillis : 0;
219-
JVM.getJVM().setMethodSamplingInterval(getId(), p);
219+
JVM.getJVM().setMethodSamplingPeriod(getId(), p);
220220
}
221221
this.beginChunk = beginChunk;
222222
this.endChunk = endChunk;

0 commit comments

Comments
 (0)