diff --git a/src/hotspot/share/runtime/threadSMR.cpp b/src/hotspot/share/runtime/threadSMR.cpp index 9b70bdf753c90..d0c9dd0ef3240 100644 --- a/src/hotspot/share/runtime/threadSMR.cpp +++ b/src/hotspot/share/runtime/threadSMR.cpp @@ -76,7 +76,7 @@ volatile uint ThreadsSMRSupport::_deleted_thread_time_max = 0; volatile uint ThreadsSMRSupport::_deleted_thread_times = 0; // The bootstrap list is empty and cannot be freed. -ThreadsList ThreadsSMRSupport::_bootstrap_list = ThreadsList(0); +ThreadsList ThreadsSMRSupport::_bootstrap_list{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 @@ -585,18 +585,32 @@ void SafeThreadsListPtr::verify_hazard_ptr_scanned() { #endif } -// 'entries + 1' so we always have at least one entry. +// Shared singleton data for all ThreadsList(0) instances. +// Used by _bootstrap_list to avoid static init time heap allocation. +// No real entries, just the final NULL terminator. +static JavaThread* const empty_threads_list_data[1] = {}; + +// Result has 'entries + 1' elements, with the last being the NULL terminator. +static JavaThread* const* make_threads_list_data(int entries) { + if (entries == 0) { + return empty_threads_list_data; + } + JavaThread** data = NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread); + data[entries] = NULL; // Make sure the final entry is NULL. + return data; +} + ThreadsList::ThreadsList(int entries) : _length(entries), _next_list(NULL), - _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread)), + _threads(make_threads_list_data(entries)), _nested_handle_cnt(0) -{ - *(JavaThread**)(_threads + entries) = NULL; // Make sure the extra entry is NULL. -} +{} ThreadsList::~ThreadsList() { - FREE_C_HEAP_ARRAY(JavaThread*, _threads); + if (_threads != empty_threads_list_data) { + FREE_C_HEAP_ARRAY(JavaThread*, _threads); + } } // Add a JavaThread to a ThreadsList. The returned ThreadsList is a diff --git a/src/hotspot/share/runtime/threadSMR.hpp b/src/hotspot/share/runtime/threadSMR.hpp index 67e1e79565e5c..79b7f8181e0e1 100644 --- a/src/hotspot/share/runtime/threadSMR.hpp +++ b/src/hotspot/share/runtime/threadSMR.hpp @@ -172,6 +172,8 @@ class ThreadsList : public CHeapObj { JavaThread *const *const _threads; volatile intx _nested_handle_cnt; + NONCOPYABLE(ThreadsList); + template void threads_do_dispatch(T *cl, JavaThread *const thread) const; @@ -185,7 +187,7 @@ class ThreadsList : public CHeapObj { static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread); public: - ThreadsList(int entries); + explicit ThreadsList(int entries); ~ThreadsList(); template