--- old/src/hotspot/share/utilities/concurrentHashTable.inline.hpp 2019-09-26 22:29:59.680235816 +0800 +++ new/src/hotspot/share/utilities/concurrentHashTable.inline.hpp 2019-09-26 22:29:59.533230697 +0800 @@ -480,6 +480,7 @@ GlobalCounter::write_synchronize(); delete_f(rem_n->value()); Node::destroy_node(rem_n); + JFR_ONLY(_stats_rate.remove();) return true; } @@ -528,6 +529,7 @@ for (size_t node_it = 0; node_it < nd; node_it++) { del_f(ndel[node_it]->value()); Node::destroy_node(ndel[node_it]); + JFR_ONLY(_stats_rate.remove();) DEBUG_ONLY(ndel[node_it] = (Node*)POISON_PTR;) } GlobalCounter::critical_section_begin(thread); @@ -564,6 +566,7 @@ GlobalCounter::write_synchronize(); for (size_t node_it = 0; node_it < dels; node_it++) { Node::destroy_node(ndel[node_it]); + JFR_ONLY(_stats_rate.remove();) DEBUG_ONLY(ndel[node_it] = (Node*)POISON_PTR;) } } @@ -898,6 +901,7 @@ new_node->set_next(first_at_start); } if (bucket->cas_first(new_node, first_at_start)) { + JFR_ONLY(_stats_rate.add();) callback(true, new_node->value()); new_node = NULL; ret = true; @@ -1004,6 +1008,7 @@ _size_limit_reached(false), _resize_lock_owner(NULL), _invisible_epoch(0) { + _stats_rate = TableRateStatistics(); _resize_lock = new Mutex(Mutex::leaf, "ConcurrentHashTable", false, Monitor::_safepoint_check_never); @@ -1087,6 +1092,7 @@ if (!bucket->cas_first(new_node, bucket->first())) { assert(false, "bad"); } + JFR_ONLY(_stats_rate.add();) return true; } @@ -1141,24 +1147,18 @@ template template -inline void ConcurrentHashTable:: - statistics_to(Thread* thread, VALUE_SIZE_FUNC& vs_f, - outputStream* st, const char* table_name) +inline TableStatistics ConcurrentHashTable:: + statistics_calculate(Thread* thread, VALUE_SIZE_FUNC& vs_f) { NumberSeq summary; size_t literal_bytes = 0; - if (!try_resize_lock(thread)) { - st->print_cr("statistics unavailable at this moment"); - return; - } - InternalTable* table = get_table(); for (size_t bucket_it = 0; bucket_it < table->_size; bucket_it++) { ScopedCS cs(thread, this); size_t count = 0; Bucket* bucket = table->get_bucket(bucket_it); if (bucket->have_redirect() || bucket->is_locked()) { - continue; + continue; } Node* current_node = bucket->first(); while (current_node != NULL) { @@ -1169,37 +1169,39 @@ summary.add((double)count); } - double num_buckets = summary.num(); - double num_entries = summary.sum(); + return TableStatistics(_stats_rate, summary, literal_bytes, sizeof(Bucket), sizeof(Node)); +} + +template +template +inline TableStatistics ConcurrentHashTable:: + statistics_get(Thread* thread, VALUE_SIZE_FUNC& vs_f, TableStatistics old) +{ + if (!try_resize_lock(thread)) { + return old; + } + + TableStatistics ts = statistics_calculate(thread, vs_f); + unlock_resize_lock(thread); + + return ts; +} + +template +template +inline void ConcurrentHashTable:: + statistics_to(Thread* thread, VALUE_SIZE_FUNC& vs_f, + outputStream* st, const char* table_name) +{ + if (!try_resize_lock(thread)) { + st->print_cr("statistics unavailable at this moment"); + return; + } - size_t bucket_bytes = num_buckets * sizeof(Bucket); - size_t entry_bytes = num_entries * sizeof(Node); - size_t total_bytes = literal_bytes + bucket_bytes + entry_bytes; - - size_t bucket_size = (num_buckets <= 0) ? 0 : (bucket_bytes / num_buckets); - size_t entry_size = (num_entries <= 0) ? 0 : (entry_bytes / num_entries); - - st->print_cr("%s statistics:", table_name); - st->print_cr("Number of buckets : %9" PRIuPTR " = %9" PRIuPTR - " bytes, each " SIZE_FORMAT, - (size_t)num_buckets, bucket_bytes, bucket_size); - st->print_cr("Number of entries : %9" PRIuPTR " = %9" PRIuPTR - " bytes, each " SIZE_FORMAT, - (size_t)num_entries, entry_bytes, entry_size); - if (literal_bytes != 0) { - double literal_avg = (num_entries <= 0) ? 0 : (literal_bytes / num_entries); - st->print_cr("Number of literals : %9" PRIuPTR " = %9" PRIuPTR - " bytes, avg %7.3f", - (size_t)num_entries, literal_bytes, literal_avg); - } - st->print_cr("Total footprsize_t : %9s = %9" PRIuPTR " bytes", "" - , total_bytes); - st->print_cr("Average bucket size : %9.3f", summary.avg()); - st->print_cr("Variance of bucket size : %9.3f", summary.variance()); - st->print_cr("Std. dev. of bucket size: %9.3f", summary.sd()); - st->print_cr("Maximum bucket size : %9" PRIuPTR, - (size_t)summary.maximum()); + TableStatistics ts = statistics_calculate(thread, vs_f); unlock_resize_lock(thread); + + ts.print(st, table_name); } template