@@ -76,7 +76,7 @@ volatile uint ThreadsSMRSupport::_deleted_thread_time_max = 0;
76
76
volatile uint ThreadsSMRSupport::_deleted_thread_times = 0 ;
77
77
78
78
// The bootstrap list is empty and cannot be freed.
79
- ThreadsList ThreadsSMRSupport::_bootstrap_list = ThreadsList( 0 ) ;
79
+ ThreadsList ThreadsSMRSupport::_bootstrap_list{ 0 } ;
80
80
81
81
// This is the VM's current "threads list" and it contains all of
82
82
// the JavaThreads the VM considers to be alive at this moment in
@@ -585,18 +585,32 @@ void SafeThreadsListPtr::verify_hazard_ptr_scanned() {
585
585
#endif
586
586
}
587
587
588
- // 'entries + 1' so we always have at least one entry.
588
+ // Shared singleton data for all ThreadsList(0) instances.
589
+ // Used by _bootstrap_list to avoid static init time heap allocation.
590
+ // No real entries, just the final NULL terminator.
591
+ static JavaThread* const empty_threads_list_data[1 ] = {};
592
+
593
+ // Result has 'entries + 1' elements, with the last being the NULL terminator.
594
+ static JavaThread* const * make_threads_list_data (int entries) {
595
+ if (entries == 0 ) {
596
+ return empty_threads_list_data;
597
+ }
598
+ JavaThread** data = NEW_C_HEAP_ARRAY (JavaThread*, entries + 1 , mtThread);
599
+ data[entries] = NULL ; // Make sure the final entry is NULL.
600
+ return data;
601
+ }
602
+
589
603
ThreadsList::ThreadsList (int entries) :
590
604
_length(entries),
591
605
_next_list(NULL ),
592
- _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1 , mtThread )),
606
+ _threads(make_threads_list_data( entries)),
593
607
_nested_handle_cnt(0 )
594
- {
595
- *(JavaThread**)(_threads + entries) = NULL ; // Make sure the extra entry is NULL.
596
- }
608
+ {}
597
609
598
610
ThreadsList::~ThreadsList () {
599
- FREE_C_HEAP_ARRAY (JavaThread*, _threads);
611
+ if (_threads != empty_threads_list_data) {
612
+ FREE_C_HEAP_ARRAY (JavaThread*, _threads);
613
+ }
600
614
}
601
615
602
616
// Add a JavaThread to a ThreadsList. The returned ThreadsList is a
0 commit comments