diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index eb27927866fda..07eb29b288987 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -223,7 +223,7 @@ void StringTable::create_table() { _current_size = ((size_t)1) << start_size_log_2; log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", _current_size, start_size_log_2); - _local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN); + _local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN, true); _oop_storage = OopStorageSet::create_weak("StringTable Weak", mtSymbol); _oop_storage->register_num_dead_callback(&gc_notification); } diff --git a/src/hotspot/share/classfile/symbolTable.cpp b/src/hotspot/share/classfile/symbolTable.cpp index fe63e6ed922ac..0e231f3c02cf1 100644 --- a/src/hotspot/share/classfile/symbolTable.cpp +++ b/src/hotspot/share/classfile/symbolTable.cpp @@ -783,7 +783,7 @@ bool SymbolTable::do_rehash() { // We use current size size_t new_size = _local_table->get_size_log2(Thread::current()); - SymbolTableHash* new_table = new SymbolTableHash(new_size, END_SIZE, REHASH_LEN); + SymbolTableHash* new_table = new SymbolTableHash(new_size, END_SIZE, REHASH_LEN, true); // Use alt hash from now on _alt_hash = true; if (!_local_table->try_move_nodes_to(Thread::current(), new_table)) { diff --git a/src/hotspot/share/gc/g1/g1CardSet.cpp b/src/hotspot/share/gc/g1/g1CardSet.cpp index 4a0ab8b4ca0fa..c1c360b07f8bd 100644 --- a/src/hotspot/share/gc/g1/g1CardSet.cpp +++ b/src/hotspot/share/gc/g1/g1CardSet.cpp @@ -280,7 +280,7 @@ class G1CardSetHashTable : public CHeapObj { size_t initial_log_table_size = InitialLogTableSize) : _inserted_card(false), _mm(mm), - _table(mm, initial_log_table_size) { + _table(mm, initial_log_table_size, false) { } ~G1CardSetHashTable() { diff --git a/src/hotspot/share/services/finalizerService.cpp b/src/hotspot/share/services/finalizerService.cpp index 4728ec9385279..b3b5eb7450b9d 100644 --- a/src/hotspot/share/services/finalizerService.cpp +++ b/src/hotspot/share/services/finalizerService.cpp @@ -270,7 +270,7 @@ void FinalizerService::do_concurrent_work(JavaThread* service_thread) { void FinalizerService::init() { assert(_table == nullptr, "invariant"); const size_t start_size_log_2 = ceil_log2(DEFAULT_TABLE_SIZE); - _table = new FinalizerHashtable(start_size_log_2, MAX_SIZE); + _table = new FinalizerHashtable(start_size_log_2, MAX_SIZE, FinalizerHashtable::DEFAULT_GROW_HINT); } static FinalizerEntry* lookup_entry(const InstanceKlass* ik, Thread* thread) { diff --git a/src/hotspot/share/services/threadIdTable.cpp b/src/hotspot/share/services/threadIdTable.cpp index c68a5d7d087c0..0e10995430793 100644 --- a/src/hotspot/share/services/threadIdTable.cpp +++ b/src/hotspot/share/services/threadIdTable.cpp @@ -122,7 +122,8 @@ void ThreadIdTable::create_table(size_t size) { size_t start_size_log = size_log > DEFAULT_TABLE_SIZE_LOG ? size_log : DEFAULT_TABLE_SIZE_LOG; _current_size = (size_t)1 << start_size_log; - _local_table = new ThreadIdTableHash(start_size_log, END_SIZE); + _local_table = + new ThreadIdTableHash(start_size_log, END_SIZE, ThreadIdTableHash::DEFAULT_GROW_HINT); } void ThreadIdTable::item_added() { diff --git a/src/hotspot/share/utilities/concurrentHashTable.hpp b/src/hotspot/share/utilities/concurrentHashTable.hpp index 37c8189497596..f6b2de3bb70f8 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.hpp @@ -42,6 +42,22 @@ template class ConcurrentHashTable : public CHeapObj { typedef typename CONFIG::Value VALUE; private: + // _stats_rate is null if statistics are not enabled. + TableRateStatistics* _stats_rate; + inline void safe_stats_add() { + if (_stats_rate != nullptr) { + _stats_rate->add(); + } + } + inline void safe_stats_remove() { + if (_stats_rate != nullptr) { + _stats_rate->remove(); + } + } + // Calculate statistics. Item sizes are calculated with VALUE_SIZE_FUNC. + template + TableStatistics statistics_calculate(Thread* thread, VALUE_SIZE_FUNC& vs_f); + // This is the internal node structure. // Only constructed with placement new from memory allocated with MEMFLAGS of // the InternalTable or user-defined memory. @@ -209,11 +225,6 @@ class ConcurrentHashTable : public CHeapObj { InternalTable* _table; // Active table. InternalTable* _new_table; // Table we are resizing to. - // Default sizes - static const size_t DEFAULT_MAX_SIZE_LOG2 = 21; - static const size_t DEFAULT_START_SIZE_LOG2 = 13; - static const size_t DEFAULT_GROW_HINT = 4; // Chain length - const size_t _log2_size_limit; // The biggest size. const size_t _log2_start_size; // Start size. const size_t _grow_hint; // Number of linked items @@ -376,18 +387,22 @@ class ConcurrentHashTable : public CHeapObj { void delete_in_bucket(Thread* thread, Bucket* bucket, LOOKUP_FUNC& lookup_f); public: + // Default sizes + static const size_t DEFAULT_MAX_SIZE_LOG2 = 21; + static const size_t DEFAULT_START_SIZE_LOG2 = 13; + static const size_t DEFAULT_GROW_HINT = 4; // Chain length + static const bool DEFAULT_ENABLE_STATISTICS = false; ConcurrentHashTable(size_t log2size = DEFAULT_START_SIZE_LOG2, size_t log2size_limit = DEFAULT_MAX_SIZE_LOG2, size_t grow_hint = DEFAULT_GROW_HINT, - void* context = NULL); + bool enable_statistics = DEFAULT_ENABLE_STATISTICS, + void* context = nullptr); - explicit ConcurrentHashTable(void* context, size_t log2size = DEFAULT_START_SIZE_LOG2) : - ConcurrentHashTable(log2size, DEFAULT_MAX_SIZE_LOG2, DEFAULT_GROW_HINT, context) {} + explicit ConcurrentHashTable(void* context, size_t log2size = DEFAULT_START_SIZE_LOG2, bool enable_statistics = DEFAULT_ENABLE_STATISTICS) : + ConcurrentHashTable(log2size, DEFAULT_MAX_SIZE_LOG2, DEFAULT_GROW_HINT, enable_statistics, context) {} ~ConcurrentHashTable(); - TableRateStatistics _stats_rate; - size_t get_mem_size(Thread* thread); size_t get_size_log2(Thread* thread); @@ -482,10 +497,6 @@ class ConcurrentHashTable : public CHeapObj { template void bulk_delete(Thread* thread, EVALUATE_FUNC& eval_f, DELETE_FUNC& del_f); - // Calculate statistics. Item sizes are calculated with VALUE_SIZE_FUNC. - template - TableStatistics statistics_calculate(Thread* thread, VALUE_SIZE_FUNC& vs_f); - // Gets statistics if available, if not return old one. Item sizes are calculated with // VALUE_SIZE_FUNC. template diff --git a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp index 5b11091194cf9..b4cbcf0a1d751 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp @@ -472,7 +472,7 @@ inline bool ConcurrentHashTable:: GlobalCounter::write_synchronize(); delete_f(rem_n->value()); Node::destroy_node(_context, rem_n); - JFR_ONLY(_stats_rate.remove();) + JFR_ONLY(safe_stats_remove();) return true; } @@ -521,7 +521,7 @@ inline void ConcurrentHashTable:: for (size_t node_it = 0; node_it < nd; node_it++) { del_f(ndel[node_it]->value()); Node::destroy_node(_context, ndel[node_it]); - JFR_ONLY(_stats_rate.remove();) + JFR_ONLY(safe_stats_remove();) DEBUG_ONLY(ndel[node_it] = (Node*)POISON_PTR;) } cs_context = GlobalCounter::critical_section_begin(thread); @@ -560,7 +560,7 @@ inline void ConcurrentHashTable:: GlobalCounter::write_synchronize(); for (size_t node_it = 0; node_it < dels; node_it++) { Node::destroy_node(_context, ndel[node_it]); - JFR_ONLY(_stats_rate.remove();) + JFR_ONLY(safe_stats_remove();) DEBUG_ONLY(ndel[node_it] = (Node*)POISON_PTR;) } } @@ -902,7 +902,7 @@ inline bool ConcurrentHashTable:: new_node->set_next(first_at_start); if (bucket->cas_first(new_node, first_at_start)) { foundf(new_node->value()); - JFR_ONLY(_stats_rate.add();) + JFR_ONLY(safe_stats_add();) new_node = NULL; ret = true; break; /* leave critical section */ @@ -1007,13 +1007,17 @@ inline size_t ConcurrentHashTable:: // Constructor template inline ConcurrentHashTable:: - ConcurrentHashTable(size_t log2size, size_t log2size_limit, size_t grow_hint, void* context) +ConcurrentHashTable(size_t log2size, size_t log2size_limit, size_t grow_hint, bool enable_statistics, void* context) : _context(context), _new_table(NULL), _log2_size_limit(log2size_limit), _log2_start_size(log2size), _grow_hint(grow_hint), _size_limit_reached(false), _resize_lock_owner(NULL), _invisible_epoch(0) { - _stats_rate = TableRateStatistics(); + if (enable_statistics) { + _stats_rate = new TableRateStatistics(); + } else { + _stats_rate = nullptr; + } _resize_lock = new Mutex(Mutex::nosafepoint-2, "ConcurrentHashTableResize_lock"); _table = new InternalTable(log2size); @@ -1028,6 +1032,7 @@ inline ConcurrentHashTable:: delete _resize_lock; free_nodes(); delete _table; + delete _stats_rate; } template @@ -1102,7 +1107,7 @@ inline bool ConcurrentHashTable:: if (!bucket->cas_first(new_node, bucket->first())) { assert(false, "bad"); } - JFR_ONLY(_stats_rate.add();) + JFR_ONLY(safe_stats_add();) return true; } @@ -1224,7 +1229,7 @@ inline TableStatistics ConcurrentHashTable:: summary.add((double)count); } - return TableStatistics(_stats_rate, summary, literal_bytes, sizeof(Bucket), sizeof(Node)); + return TableStatistics(*_stats_rate, summary, literal_bytes, sizeof(Bucket), sizeof(Node)); } template diff --git a/src/hotspot/share/utilities/tableStatistics.hpp b/src/hotspot/share/utilities/tableStatistics.hpp index d32729e4629e5..d4fd330292246 100644 --- a/src/hotspot/share/utilities/tableStatistics.hpp +++ b/src/hotspot/share/utilities/tableStatistics.hpp @@ -30,7 +30,7 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/numberSeq.hpp" -class TableRateStatistics : CHeapObj { +class TableRateStatistics : public CHeapObj { friend class TableStatistics;