comparison src/hotspot/share/utilities/hashtable.cpp @ 57831:40be0504668d

Automatic merge with records-and-sealed
author mcimadamore
date Tue, 17 Sep 2019 22:26:59 +0000
parents 5c7418757bad
children aba258cd7df8
comparison
equal deleted inserted replaced
14:d5b2b0b939f1 15:b9e41abd029f
189 } else { 189 } else {
190 return false; 190 return false;
191 } 191 }
192 } 192 }
193 193
194 // Dump footprint and bucket length statistics 194 template <class T, MEMFLAGS F> TableStatistics Hashtable<T, F>::statistics_calculate(T (*literal_load_barrier)(HashtableEntry<T, F>*)) {
195 //
196 // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to
197 // add a new function static int literal_size(MyNewType lit)
198 // because I can't get template <class T> int literal_size(T) to pick the specializations for Symbol and oop.
199 //
200 // The StringTable and SymbolTable dumping print how much footprint is used by the String and Symbol
201 // literals.
202
203 template <class T, MEMFLAGS F> void Hashtable<T, F>::print_table_statistics(outputStream* st,
204 const char *table_name,
205 T (*literal_load_barrier)(HashtableEntry<T, F>*)) {
206 NumberSeq summary; 195 NumberSeq summary;
207 int literal_bytes = 0; 196 int literal_bytes = 0;
208 for (int i = 0; i < this->table_size(); ++i) { 197 for (int i = 0; i < this->table_size(); ++i) {
209 int count = 0; 198 int count = 0;
210 for (HashtableEntry<T, F>* e = this->bucket(i); 199 for (HashtableEntry<T, F>* e = this->bucket(i);
213 T l = (literal_load_barrier != NULL) ? literal_load_barrier(e) : e->literal(); 202 T l = (literal_load_barrier != NULL) ? literal_load_barrier(e) : e->literal();
214 literal_bytes += literal_size(l); 203 literal_bytes += literal_size(l);
215 } 204 }
216 summary.add((double)count); 205 summary.add((double)count);
217 } 206 }
218 double num_buckets = summary.num(); 207 return TableStatistics(this->_stats_rate, summary, literal_bytes, sizeof(HashtableBucket<F>), sizeof(HashtableEntry<T, F>));
219 double num_entries = summary.sum(); 208 }
220 209
221 int bucket_bytes = (int)num_buckets * sizeof(HashtableBucket<F>); 210 // Dump footprint and bucket length statistics
222 int entry_bytes = (int)num_entries * sizeof(HashtableEntry<T, F>); 211 //
223 int total_bytes = literal_bytes + bucket_bytes + entry_bytes; 212 // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to
224 213 // add a new function static int literal_size(MyNewType lit)
225 int bucket_size = (num_buckets <= 0) ? 0 : (bucket_bytes / num_buckets); 214 // because I can't get template <class T> int literal_size(T) to pick the specializations for Symbol and oop.
226 int entry_size = (num_entries <= 0) ? 0 : (entry_bytes / num_entries); 215 template <class T, MEMFLAGS F> void Hashtable<T, F>::print_table_statistics(outputStream* st,
227 216 const char *table_name,
228 st->print_cr("%s statistics:", table_name); 217 T (*literal_load_barrier)(HashtableEntry<T, F>*)) {
229 st->print_cr("Number of buckets : %9d = %9d bytes, each %d", (int)num_buckets, bucket_bytes, bucket_size); 218 TableStatistics ts = statistics_calculate(literal_load_barrier);
230 st->print_cr("Number of entries : %9d = %9d bytes, each %d", (int)num_entries, entry_bytes, entry_size); 219 ts.print(st, table_name);
231 if (literal_bytes != 0) {
232 double literal_avg = (num_entries <= 0) ? 0 : (literal_bytes / num_entries);
233 st->print_cr("Number of literals : %9d = %9d bytes, avg %7.3f", (int)num_entries, literal_bytes, literal_avg);
234 }
235 st->print_cr("Total footprint : %9s = %9d bytes", "", total_bytes);
236 st->print_cr("Average bucket size : %9.3f", summary.avg());
237 st->print_cr("Variance of bucket size : %9.3f", summary.variance());
238 st->print_cr("Std. dev. of bucket size: %9.3f", summary.sd());
239 st->print_cr("Maximum bucket size : %9d", (int)summary.maximum());
240 } 220 }
241 221
242 #ifndef PRODUCT 222 #ifndef PRODUCT
243 template <class T> void print_literal(T l) { 223 template <class T> void print_literal(T l) {
244 l->print(); 224 l->print();