diff --git a/src/share/vm/jfr/metadata/metadata.xml b/src/share/vm/jfr/metadata/metadata.xml index 359b095b8aab6453d686e746f3268df3d2e5efa3..7ae07951b60422ba0ebf1ada7758aa3f64a4fa01 100644 --- a/src/share/vm/jfr/metadata/metadata.xml +++ b/src/share/vm/jfr/metadata/metadata.xml @@ -26,8 +26,9 @@ - - + + + diff --git a/src/share/vm/jfr/support/jfrThreadLocal.cpp b/src/share/vm/jfr/support/jfrThreadLocal.cpp index 8d6ea9557296c36ae896d27dd0e8ce23a858a1e6..bc26529c6e0bed42b6d92e2eb6a3cdbd165819c2 100644 --- a/src/share/vm/jfr/support/jfrThreadLocal.cpp +++ b/src/share/vm/jfr/support/jfrThreadLocal.cpp @@ -60,7 +60,11 @@ JfrThreadLocal::JfrThreadLocal() : _cached_top_frame_bci(max_jint), _alloc_count(0), _alloc_count_until_sample(1), - _cached_event_id(MaxJfrEventId) {} + _cached_event_id(MaxJfrEventId) { + + Thread* thread = ThreadLocalStorage::thread(); + _parent_trace_id = thread != NULL ? thread->jfr_thread_local()->trace_id() : (traceid)0; +} u8 JfrThreadLocal::add_data_lost(u8 value) { _data_lost += value; @@ -83,6 +87,7 @@ const JfrBlobHandle& JfrThreadLocal::thread_blob() const { static void send_java_thread_start_event(JavaThread* jt) { EventThreadStart event; event.set_thread(jt->jfr_thread_local()->thread_id()); + event.set_parentThread(jt->jfr_thread_local()->parent_thread_id()); event.commit(); } @@ -98,6 +103,9 @@ void JfrThreadLocal::on_start(Thread* t) { } } } + if (t->jfr_thread_local()->has_cached_stack_trace()) { + t->jfr_thread_local()->clear_cached_stack_trace(); + } } static void send_java_thread_end_events(traceid id, JavaThread* jt) { diff --git a/src/share/vm/jfr/support/jfrThreadLocal.hpp b/src/share/vm/jfr/support/jfrThreadLocal.hpp index 3c5292805c05d0742c91319a77aba2b5608a852e..3662a30f9a6529469d4c87a8f85e9bc9ad26dc6e 100644 --- a/src/share/vm/jfr/support/jfrThreadLocal.hpp +++ b/src/share/vm/jfr/support/jfrThreadLocal.hpp @@ -52,6 +52,7 @@ class JfrThreadLocal { volatile jint _entering_suspend_flag; bool _excluded; bool _dead; + traceid _parent_trace_id; // Jfr callstack collection relies on vframeStream. // But the bci of top frame can not be determined by vframeStream in some scenarios. // For example, in the opto CallLeafNode runtime call of @@ -149,6 +150,10 @@ class JfrThreadLocal { _trace_id = thread_id; } + traceid parent_thread_id() const { + return _parent_trace_id; + } + void set_cached_stack_trace_id(traceid id, unsigned int hash = 0) { _stack_trace_id = id; _stack_trace_hash = hash; diff --git a/src/share/vm/prims/jni.cpp b/src/share/vm/prims/jni.cpp index a4a387dcd2dfb500337b77d67ff42a8982bb93ba..221fe4a4cbcba46ad326ac4d6d57385961101263 100644 --- a/src/share/vm/prims/jni.cpp +++ b/src/share/vm/prims/jni.cpp @@ -5025,7 +5025,14 @@ static void post_thread_start_event(const JavaThread* jt) { EventThreadStart event; if (event.should_commit()) { event.set_thread(JFR_THREAD_ID(jt)); - event.commit(); + event.set_parentThread((traceid)0); + if (EventThreadStart::is_stacktrace_enabled()) { + jt->jfr_thread_local()->set_cached_stack_trace_id((traceid)0); + event.commit(); + jt->jfr_thread_local()->clear_cached_stack_trace(); + } else { + event.commit(); + } } } diff --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp index ffdaf4be5f102165cc09ca7adbd198c72fb4672c..8e539df3116a64d17021adc812f548e5773681db 100644 --- a/src/share/vm/prims/jvm.cpp +++ b/src/share/vm/prims/jvm.cpp @@ -101,6 +101,7 @@ #endif // INCLUDE_ALL_GCS #include +#include #ifndef USDT2 HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__begin, long long); @@ -3230,6 +3231,15 @@ JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) "unable to create new native thread"); } +#if INCLUDE_JFR + if (JfrRecorder::is_recording() && EventThreadStart::is_enabled() && + EventThreadStart::is_stacktrace_enabled()) { + JfrThreadLocal* tl = native_thread->jfr_thread_local(); + // skip Thread.start() and Thread.start0() + tl->set_cached_stack_trace_id(JfrStackTraceRepository::record(thread, 2, WALK_BY_DEFAULT)); + } +#endif + Thread::start(native_thread); JVM_END @@ -5054,4 +5064,4 @@ JVM_ENTRY(void, JVM_MarkPreempted(JNIEnv* env, jclass klass, jobject threadObj, VM_ForceSafepoint force_safepoint_op; VMThread::execute(&force_safepoint_op); } -JVM_END \ No newline at end of file +JVM_END