< prev index next >
src/hotspot/share/utilities/hashtable.cpp
Print this page
rev 52316 : 8185525: Add JFR event for DictionarySizes
Summary: Added TableStatistics event
Reviewed-by: egahlin, coleenp
*** 308,329 ****
_buckets = buckets_new;
return true;
}
! // Dump footprint and bucket length statistics
! //
! // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to
! // add a new function static int literal_size(MyNewType lit)
! // because I can't get template <class T> int literal_size(T) to pick the specializations for Symbol and oop.
! //
! // The StringTable and SymbolTable dumping print how much footprint is used by the String and Symbol
! // literals.
!
! template <class T, MEMFLAGS F> void Hashtable<T, F>::print_table_statistics(outputStream* st,
! const char *table_name,
! T (*literal_load_barrier)(HashtableEntry<T, F>*)) {
NumberSeq summary;
int literal_bytes = 0;
for (int i = 0; i < this->table_size(); ++i) {
int count = 0;
for (HashtableEntry<T, F>* e = this->bucket(i);
--- 308,318 ----
_buckets = buckets_new;
return true;
}
! template <class T, MEMFLAGS F> TableStatistics Hashtable<T, F>::statistics_calculate(T (*literal_load_barrier)(HashtableEntry<T, F>*)) {
NumberSeq summary;
int literal_bytes = 0;
for (int i = 0; i < this->table_size(); ++i) {
int count = 0;
for (HashtableEntry<T, F>* e = this->bucket(i);
*** 332,363 ****
T l = (literal_load_barrier != NULL) ? literal_load_barrier(e) : e->literal();
literal_bytes += literal_size(l);
}
summary.add((double)count);
}
! double num_buckets = summary.num();
! double num_entries = summary.sum();
! int bucket_bytes = (int)num_buckets * sizeof(HashtableBucket<F>);
! int entry_bytes = (int)num_entries * sizeof(HashtableEntry<T, F>);
! int total_bytes = literal_bytes + bucket_bytes + entry_bytes;
!
! int bucket_size = (num_buckets <= 0) ? 0 : (bucket_bytes / num_buckets);
! int entry_size = (num_entries <= 0) ? 0 : (entry_bytes / num_entries);
!
! st->print_cr("%s statistics:", table_name);
! st->print_cr("Number of buckets : %9d = %9d bytes, each %d", (int)num_buckets, bucket_bytes, bucket_size);
! st->print_cr("Number of entries : %9d = %9d bytes, each %d", (int)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 : %9d = %9d bytes, avg %7.3f", (int)num_entries, literal_bytes, literal_avg);
! }
! st->print_cr("Total footprint : %9s = %9d 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 : %9d", (int)summary.maximum());
}
// Dump the hash table buckets.
--- 321,343 ----
T l = (literal_load_barrier != NULL) ? literal_load_barrier(e) : e->literal();
literal_bytes += literal_size(l);
}
summary.add((double)count);
}
! return TableStatistics(this->_stats_rate, summary, literal_bytes, sizeof(HashtableBucket<F>), sizeof(HashtableEntry<T, F>));
! }
! // Dump footprint and bucket length statistics
! //
! // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to
! // add a new function static int literal_size(MyNewType lit)
! // because I can't get template <class T> int literal_size(T) to pick the specializations for Symbol and oop.
! template <class T, MEMFLAGS F> void Hashtable<T, F>::print_table_statistics(outputStream* st,
! const char *table_name,
! T (*literal_load_barrier)(HashtableEntry<T, F>*)) {
! TableStatistics ts = statistics_calculate(literal_load_barrier);
! ts.print(st, table_name);
}
// Dump the hash table buckets.
< prev index next >