Thread metadata to include excluded threads, thread sampler to exclude excluded threads, thread name friend JEP-349-branch
authormgronlun
Mon, 26 Aug 2019 13:09:14 +0200
branchJEP-349-branch
changeset 57878 bffba8d6611a
parent 57874 cd496c5a3823
child 57882 562f598d303c
Thread metadata to include excluded threads, thread sampler to exclude excluded threads, thread name friend
src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp
src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp
src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp
src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.hpp
src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp
src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp
src/hotspot/share/jfr/utilities/jfrThreadIterator.cpp
src/hotspot/share/runtime/thread.cpp
src/hotspot/share/runtime/thread.hpp
--- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Mon Aug 26 13:09:14 2019 +0200
@@ -422,7 +422,6 @@
     while (iter.has_next()) {
       JavaThread* const jt = iter.next();
       assert(jt != NULL, "invariant");
-
       allocated.append(jt->cooked_allocated_bytes());
       thread_ids.append(JFR_THREAD_ID(jt));
     }
--- a/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp	Mon Aug 26 13:09:14 2019 +0200
@@ -119,6 +119,9 @@
   while (iter.has_next()) {
     JavaThread* const jt = iter.next();
     assert(jt != NULL, "invariant");
+    if (jt->jfr_thread_local()->is_excluded()) {
+      continue;
+    }
     ++number_of_threads;
     EventThreadCPULoad event(UNTIMED);
     if (JfrThreadCPULoadEvent::update_event(event, jt, cur_wallclock_time, processor_count)) {
--- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp	Mon Aug 26 13:09:14 2019 +0200
@@ -30,6 +30,7 @@
 #include "jfr/recorder/service/jfrOptionSet.hpp"
 #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
 #include "jfr/support/jfrThreadId.hpp"
+#include "jfr/support/jfrThreadLocal.hpp"
 #include "jfr/utilities/jfrTime.hpp"
 #include "logging/log.hpp"
 #include "runtime/frame.inline.hpp"
@@ -352,9 +353,14 @@
   }
 }
 
+static bool is_excluded(JavaThread* thread) {
+  assert(thread != NULL, "invariant");
+  return thread->is_hidden_from_external_view() || thread->in_deopt_handler() || thread->jfr_thread_local()->is_excluded();
+}
+
 bool JfrThreadSampleClosure::do_sample_thread(JavaThread* thread, JfrStackFrame* frames, u4 max_frames, JfrSampleType type) {
   assert(Threads_lock->owned_by_self(), "Holding the thread table lock.");
-  if (thread->is_hidden_from_external_view() || thread->in_deopt_handler()) {
+  if (is_excluded(thread)) {
     return false;
   }
 
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp	Mon Aug 26 13:09:14 2019 +0200
@@ -23,9 +23,13 @@
 */
 
 #include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
 #include "jfr/recorder/checkpoint/types/jfrThreadState.hpp"
 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
+#include "jfr/support/jfrThreadLocal.hpp"
 #include "jvmtifiles/jvmti.h"
+#include "runtime/osThread.hpp"
+#include "runtime/thread.hpp"
 
 struct jvmti_thread_state {
   u8 id;
@@ -80,3 +84,33 @@
   }
 }
 
+const char* JfrThreadName::name(const Thread* t) {
+  assert(t != NULL, "invariant");
+  if (!t->is_Java_thread()) {
+    return t->name();
+  }
+  assert(t->is_Java_thread(), "invariant");
+  const JavaThread* const jt = (JavaThread*)t;
+  return jt->get_thread_name_string();
+}
+
+traceid JfrThreadId::id(const Thread* t) {
+  assert(t != NULL, "invariant");
+  if (!t->is_Java_thread()) {
+    return os_id(t);
+  }
+  const JavaThread* const jt = (JavaThread*)t;
+  const oop thread_obj = jt->threadObj();
+  return thread_obj != NULL ? java_lang_Thread::thread_id(thread_obj) : 0;
+}
+
+traceid JfrThreadId::os_id(const Thread* t) {
+  assert(t != NULL, "invariant");
+  const OSThread* const os_thread = t->osthread();
+  return os_thread != NULL ? os_thread->thread_id() : 0;
+}
+
+traceid JfrThreadId::jfr_id(const Thread* t) {
+  assert(t != NULL, "invariant");
+  return t->jfr_thread_local()->thread_id();
+}
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.hpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.hpp	Mon Aug 26 13:09:14 2019 +0200
@@ -28,10 +28,24 @@
 #include "memory/allocation.hpp"
 
 class JfrCheckpointWriter;
+class Thread;
 
 class JfrThreadState : public AllStatic {
  public:
   static void serialize(JfrCheckpointWriter& writer);
 };
 
+class JfrThreadName : public AllStatic {
+ public:
+  // Requires a ResourceMark for get_thread_name/as_utf8
+  static const char* name(const Thread* t);
+};
+
+class JfrThreadId : public AllStatic {
+ public:
+  static traceid id(const Thread* t);
+  static traceid os_id(const Thread* t);
+  static traceid jfr_id(const Thread* t);
+};
+
 #endif // SHARE_JFR_RECORDER_CHECKPOINT_TYPES_JFRTHREADSTATE_HPP
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp	Mon Aug 26 13:09:14 2019 +0200
@@ -38,7 +38,6 @@
 #include "jfr/recorder/checkpoint/types/jfrThreadGroup.hpp"
 #include "jfr/recorder/checkpoint/types/jfrThreadState.hpp"
 #include "jfr/recorder/checkpoint/types/jfrTypeSet.hpp"
-#include "jfr/support/jfrThreadLocal.hpp"
 #include "jfr/utilities/jfrThreadIterator.hpp"
 #include "memory/metaspaceGCThresholdUpdater.hpp"
 #include "memory/referenceType.hpp"
@@ -90,24 +89,18 @@
   void do_thread(Thread* t);
 };
 
-// Requires a ResourceMark for get_thread_name/as_utf8
 void JfrCheckpointThreadClosure::do_thread(Thread* t) {
   assert(t != NULL, "invariant");
-  const JfrThreadLocal* const tl = t->jfr_thread_local();
-  assert(tl != NULL, "invariant");
-  assert(!tl->is_dead(), "invariant");
-  assert(!tl->is_excluded(), "invariant");
   ++_count;
-  _writer.write_key(tl->thread_id());
-  _writer.write(t->name());
-  const OSThread* const os_thread = t->osthread();
-  _writer.write<traceid>(os_thread != NULL ? os_thread->thread_id() : 0);
+  _writer.write_key(JfrThreadId::jfr_id(t));
+  const char* const name = JfrThreadName::name(t);
+  _writer.write(name);
+  _writer.write<traceid>(JfrThreadId::os_id(t));
   if (t->is_Java_thread()) {
+    _writer.write(name);
+    _writer.write(JfrThreadId::id(t));
     JavaThread* const jt = (JavaThread*)t;
-    _writer.write(jt->name());
-    _writer.write(java_lang_Thread::thread_id(jt->threadObj()));
     _writer.write(JfrThreadGroup::thread_group_id(jt, _curthread));
-    // since we are iterating threads during a safepoint, also issue notification
     return;
   }
   _writer.write((const char*)NULL); // java name
@@ -347,17 +340,15 @@
 void JfrThreadConstant::serialize(JfrCheckpointWriter& writer) {
   assert(_thread != NULL, "invariant");
   assert(_thread == Thread::current(), "invariant");
-  ResourceMark rm(_thread);
-  HandleMark hm(_thread);
-  const char* const thread_name = _thread->name();
   writer.write_count(1);
-  writer.write_key(_thread->jfr_thread_local()->thread_id());
-  writer.write(thread_name);
-  writer.write((traceid)_thread->osthread()->thread_id());
+  writer.write_key(JfrThreadId::jfr_id(_thread));
+  const char* const name = JfrThreadName::name(_thread);
+  writer.write(name);
+  writer.write(JfrThreadId::os_id(_thread));
   if (_thread->is_Java_thread()) {
+    writer.write(name);
+    writer.write(JfrThreadId::id(_thread));
     JavaThread* const jt = (JavaThread*)_thread;
-    writer.write(jt->name());
-    writer.write(java_lang_Thread::thread_id(jt->threadObj()));
     const traceid thread_group_id = JfrThreadGroup::thread_group_id(jt, jt);
     writer.write(thread_group_id);
     JfrThreadGroup::serialize(&writer, thread_group_id);
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp	Mon Aug 26 13:09:14 2019 +0200
@@ -30,6 +30,8 @@
 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp"
 #include "jfr/utilities/jfrDoublyLinkedList.hpp"
 #include "jfr/utilities/jfrIterator.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
 #include "utilities/exceptions.hpp"
@@ -175,6 +177,8 @@
 
 void JfrTypeManager::create_thread_checkpoint(Thread* t) {
   assert(t != NULL, "invariant");
+  ResourceMark rm(t);
+  HandleMark hm(t);
   JfrThreadConstant type_thread(t);
   JfrCheckpointWriter writer(t);
   writer.write_type(TYPE_THREAD);
@@ -186,6 +190,8 @@
 
 void JfrTypeManager::write_thread_checkpoint(Thread* t) {
   assert(t != NULL, "invariant");
+  ResourceMark rm(t);
+  HandleMark hm(t);
   JfrThreadConstant type_thread(t);
   JfrCheckpointWriter writer(t);
   writer.write_type(TYPE_THREAD);
--- a/src/hotspot/share/jfr/utilities/jfrThreadIterator.cpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/jfr/utilities/jfrThreadIterator.cpp	Mon Aug 26 13:09:14 2019 +0200
@@ -29,7 +29,7 @@
 
 static bool thread_inclusion_predicate(Thread* t) {
   assert(t != NULL, "invariant");
-  return !(t->jfr_thread_local()->is_excluded() || t->jfr_thread_local()->is_dead());
+  return !t->jfr_thread_local()->is_dead();
 }
 
 static bool java_thread_inclusion_predicate(JavaThread* jt) {
--- a/src/hotspot/share/runtime/thread.cpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/runtime/thread.cpp	Mon Aug 26 13:09:14 2019 +0200
@@ -3075,6 +3075,17 @@
 // if vm exit occurs during initialization). These cases can all be accounted
 // for such that this method never returns NULL.
 const char* JavaThread::get_thread_name() const {
+#ifdef ASSERT
+  // early safepoints can hit while current thread does not yet have TLS
+  if (!SafepointSynchronize::is_at_safepoint()) {
+    Thread *cur = Thread::current();
+    if (!(cur->is_Java_thread() && cur == this)) {
+      // Current JavaThreads are allowed to get their own name without
+      // the Threads_lock.
+      assert_locked_or_safepoint(Threads_lock);
+    }
+  }
+#endif // ASSERT
   return get_thread_name_string();
 }
 
--- a/src/hotspot/share/runtime/thread.hpp	Sun Aug 25 19:09:22 2019 +0200
+++ b/src/hotspot/share/runtime/thread.hpp	Mon Aug 26 13:09:14 2019 +0200
@@ -979,6 +979,7 @@
 typedef void (*ThreadFunction)(JavaThread*, TRAPS);
 
 class JavaThread: public Thread {
+  friend class JfrThreadName;
   friend class VMStructs;
   friend class JVMCIVMStructs;
   friend class WhiteBox;