# HG changeset patch # User rehn # Date 1541687483 -3600 # Node ID 3315e47741c7f9059a6442dd2f4fc0f66b80de1b # Parent 82de990dfa109796f094df646ccf3a5db99b311b 8209139: globalCounter bootstrap issue Reviewed-by: dcubed, dholmes diff -r 82de990dfa10 -r 3315e47741c7 src/hotspot/share/runtime/threadSMR.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) { diff -r 82de990dfa10 -r 3315e47741c7 src/hotspot/share/runtime/threadSMR.hpp --- 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); diff -r 82de990dfa10 -r 3315e47741c7 src/hotspot/share/utilities/globalCounter.cpp --- 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(); ) {