8209139: globalCounter bootstrap issue
authorrehn
Thu, 08 Nov 2018 15:31:23 +0100
changeset 52452 3315e47741c7
parent 52451 82de990dfa10
child 52453 6e99148dbf33
8209139: globalCounter bootstrap issue Reviewed-by: dcubed, dholmes
src/hotspot/share/runtime/threadSMR.cpp
src/hotspot/share/runtime/threadSMR.hpp
src/hotspot/share/utilities/globalCounter.cpp
--- a/src/hotspot/share/runtime/threadSMR.cpp	Thu Nov 08 15:11:32 2018 +0100
+++ b/src/hotspot/share/runtime/threadSMR.cpp	Thu Nov 08 15:31:23 2018 +0100
@@ -70,7 +70,16 @@
 // isn't available everywhere (or is it?).
 volatile uint         ThreadsSMRSupport::_deleted_thread_times = 0;
 
-ThreadsList* volatile ThreadsSMRSupport::_java_thread_list = new ThreadsList(0);
+// The bootstrap list is empty and cannot be freed.
+ThreadsList ThreadsSMRSupport::_bootstrap_list = ThreadsList(0);
+
+// This is the VM's current "threads list" and it contains all of
+// the JavaThreads the VM considers to be alive at this moment in
+// time. The other ThreadsList objects in the VM contain past
+// snapshots of the "threads list". _java_thread_list is initially
+// set to _bootstrap_list so that we can detect when we have a very
+// early use of a ThreadsListHandle.
+ThreadsList* volatile ThreadsSMRSupport::_java_thread_list = &_bootstrap_list;
 
 // # of ThreadsLists allocated over VM lifetime.
 // Impl note: We allocate a new ThreadsList for every thread create and
@@ -135,6 +144,10 @@
   _java_thread_list_alloc_cnt++;
 }
 
+inline bool ThreadsSMRSupport::is_bootstrap_list(ThreadsList* list) {
+  return list == &_bootstrap_list;
+}
+
 inline void ThreadsSMRSupport::update_deleted_thread_time_max(uint new_value) {
   while (true) {
     uint cur_value = _deleted_thread_time_max;
@@ -159,7 +172,6 @@
   return (ThreadsList*)Atomic::xchg(new_list, &_java_thread_list);
 }
 
-
 // Hash table of pointers found by a scan. Used for collecting hazard
 // pointers (ThreadsList references). Also used for collecting JavaThreads
 // that are indirectly referenced by hazard ptrs. An instance of this
@@ -510,6 +522,11 @@
 #ifdef ASSERT
   assert(_list != NULL, "_list must not be NULL");
 
+  if (ThreadsSMRSupport::is_bootstrap_list(_list)) {
+    // We are early in VM bootstrapping so nothing to do here.
+    return;
+  }
+
   // The closure will attempt to verify that the calling thread can
   // be found by threads_do() on the specified ThreadsList. If it
   // is successful, then the specified ThreadsList was acquired as
@@ -762,6 +779,13 @@
 void ThreadsSMRSupport::free_list(ThreadsList* threads) {
   assert_locked_or_safepoint(Threads_lock);
 
+  if (is_bootstrap_list(threads)) {
+    // The bootstrap list cannot be freed and is empty so
+    // it does not need to be scanned. Nothing to do here.
+    log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::free_list: bootstrap ThreadsList=" INTPTR_FORMAT " is no longer in use.", os::current_thread_id(), p2i(threads));
+    return;
+  }
+
   threads->set_next_list(_to_delete_list);
   _to_delete_list = threads;
   if (EnableThreadSMRStatistics) {
--- a/src/hotspot/share/runtime/threadSMR.hpp	Thu Nov 08 15:11:32 2018 +0100
+++ b/src/hotspot/share/runtime/threadSMR.hpp	Thu Nov 08 15:31:23 2018 +0100
@@ -105,6 +105,7 @@
   static volatile uint         _deleted_thread_cnt;
   static volatile uint         _deleted_thread_time_max;
   static volatile uint         _deleted_thread_times;
+  static ThreadsList           _bootstrap_list;
   static ThreadsList* volatile _java_thread_list;
   static uint64_t              _java_thread_list_alloc_cnt;
   static uint64_t              _java_thread_list_free_cnt;
@@ -142,6 +143,7 @@
   static void add_thread(JavaThread *thread);
   static ThreadsList* get_java_thread_list();
   static bool is_a_protected_JavaThread_with_lock(JavaThread *thread);
+  static bool is_bootstrap_list(ThreadsList* list);
   static void remove_thread(JavaThread *thread);
   static void smr_delete(JavaThread *thread);
   static void update_tlh_stats(uint millis);
--- a/src/hotspot/share/utilities/globalCounter.cpp	Thu Nov 08 15:11:32 2018 +0100
+++ b/src/hotspot/share/utilities/globalCounter.cpp	Thu Nov 08 15:31:23 2018 +0100
@@ -61,11 +61,6 @@
   // Atomic::add must provide fence since we have storeload dependency.
   uintx gbl_cnt = Atomic::add(COUNTER_INCREMENT, &_global_counter._counter);
 
-  // Handle bootstrap
-  if (Threads::number_of_threads() == 0) {
-    return;
-  }
-
   // Do all RCU threads.
   CounterThreadCheck ctc(gbl_cnt);
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {