< prev index next >

src/hotspot/share/utilities/hashtable.cpp

Print this page




 174   // Switch to the new storage
 175   _buckets = buckets_new;
 176 
 177   return true;
 178 }
 179 
 180 template <MEMFLAGS F> bool BasicHashtable<F>::maybe_grow(int max_size, int load_factor) {
 181   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 182 
 183   if (table_size() >= max_size) {
 184     return false;
 185   }
 186   if (number_of_entries() / table_size() > load_factor) {
 187     resize(MIN2<int>(table_size() * 2, max_size));
 188     return true;
 189   } else {
 190     return false;
 191   }
 192 }
 193 
 194 // Dump footprint and bucket length statistics
 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;
 207   int literal_bytes = 0;
 208   for (int i = 0; i < this->table_size(); ++i) {
 209     int count = 0;
 210     for (HashtableEntry<T, F>* e = this->bucket(i);
 211          e != NULL; e = e->next()) {
 212       count++;
 213       T l = (literal_load_barrier != NULL) ? literal_load_barrier(e) : e->literal();
 214       literal_bytes += literal_size(l);
 215     }
 216     summary.add((double)count);
 217   }
 218   double num_buckets = summary.num();
 219   double num_entries = summary.sum();
 220 
 221   int bucket_bytes = (int)num_buckets * sizeof(HashtableBucket<F>);
 222   int entry_bytes  = (int)num_entries * sizeof(HashtableEntry<T, F>);
 223   int total_bytes = literal_bytes +  bucket_bytes + entry_bytes;
 224 
 225   int bucket_size  = (num_buckets <= 0) ? 0 : (bucket_bytes  / num_buckets);
 226   int entry_size   = (num_entries <= 0) ? 0 : (entry_bytes   / num_entries);
 227 
 228   st->print_cr("%s statistics:", table_name);
 229   st->print_cr("Number of buckets       : %9d = %9d bytes, each %d", (int)num_buckets, bucket_bytes,  bucket_size);
 230   st->print_cr("Number of entries       : %9d = %9d bytes, each %d", (int)num_entries, entry_bytes,   entry_size);
 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 }
 241 
 242 #ifndef PRODUCT
 243 template <class T> void print_literal(T l) {
 244   l->print();
 245 }
 246 
 247 static void print_literal(WeakHandle<vm_class_loader_data> l) {
 248   l.print();
 249 }
 250 
 251 template <class T, MEMFLAGS F> void Hashtable<T, F>::print() {
 252   ResourceMark rm;
 253 
 254   for (int i = 0; i < BasicHashtable<F>::table_size(); i++) {
 255     HashtableEntry<T, F>* entry = bucket(i);
 256     while(entry != NULL) {
 257       tty->print("%d : ", i);
 258       print_literal(entry->literal());
 259       tty->cr();




 174   // Switch to the new storage
 175   _buckets = buckets_new;
 176 
 177   return true;
 178 }
 179 
 180 template <MEMFLAGS F> bool BasicHashtable<F>::maybe_grow(int max_size, int load_factor) {
 181   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 182 
 183   if (table_size() >= max_size) {
 184     return false;
 185   }
 186   if (number_of_entries() / table_size() > load_factor) {
 187     resize(MIN2<int>(table_size() * 2, max_size));
 188     return true;
 189   } else {
 190     return false;
 191   }
 192 }
 193 
 194 template <class T, MEMFLAGS F> TableStatistics Hashtable<T, F>::statistics_calculate(T (*literal_load_barrier)(HashtableEntry<T, F>*)) {











 195   NumberSeq summary;
 196   int literal_bytes = 0;
 197   for (int i = 0; i < this->table_size(); ++i) {
 198     int count = 0;
 199     for (HashtableEntry<T, F>* e = this->bucket(i);
 200          e != NULL; e = e->next()) {
 201       count++;
 202       T l = (literal_load_barrier != NULL) ? literal_load_barrier(e) : e->literal();
 203       literal_bytes += literal_size(l);
 204     }
 205     summary.add((double)count);
 206   }
 207   return TableStatistics(this->_stats_rate, summary, literal_bytes, sizeof(HashtableBucket<F>), sizeof(HashtableEntry<T, F>));
 208 }
 209 
 210 // Dump footprint and bucket length statistics
 211 //
 212 // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to
 213 // add a new function static int literal_size(MyNewType lit)
 214 // because I can't get template <class T> int literal_size(T) to pick the specializations for Symbol and oop.
 215 template <class T, MEMFLAGS F> void Hashtable<T, F>::print_table_statistics(outputStream* st,
 216                                                                             const char *table_name,
 217                                                                             T (*literal_load_barrier)(HashtableEntry<T, F>*)) {
 218   TableStatistics ts = statistics_calculate(literal_load_barrier);
 219   ts.print(st, table_name);









 220 }
 221 
 222 #ifndef PRODUCT
 223 template <class T> void print_literal(T l) {
 224   l->print();
 225 }
 226 
 227 static void print_literal(WeakHandle<vm_class_loader_data> l) {
 228   l.print();
 229 }
 230 
 231 template <class T, MEMFLAGS F> void Hashtable<T, F>::print() {
 232   ResourceMark rm;
 233 
 234   for (int i = 0; i < BasicHashtable<F>::table_size(); i++) {
 235     HashtableEntry<T, F>* entry = bucket(i);
 236     while(entry != NULL) {
 237       tty->print("%d : ", i);
 238       print_literal(entry->literal());
 239       tty->cr();


< prev index next >