< prev index next >

src/share/vm/utilities/hashtable.cpp

Print this page
rev 9056 : 8185525: Add JFR event for DictionarySizes
Summary: Added TableStatistics event
Reviewed-by: egahlin, coleenp

@@ -266,20 +266,32 @@
       *bucket_addr(i) = high_list;
     }
   }
 }
 
-template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(Symbol *symbol) {
+// For oops and Strings the size of the literal is interesting. For other types, nobody cares.
+int literal_size(ConstantPool*) { return 0; }
+int literal_size(Klass*)        { return 0; }
+#if INCLUDE_ALL_GCS
+int literal_size(nmethod*)      { return 0; }
+#endif
+
+int literal_size(Symbol *symbol) {
   return symbol->size() * HeapWordSize;
 }
 
-template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(oop oop) {
+int literal_size(oop obj) {
   // NOTE: this would over-count if (pre-JDK8) java_lang_Class::has_offset_field() is true,
   // and the String.value array is shared by several Strings. However, starting from JDK8,
   // the String.value array is not shared anymore.
-  assert(oop != NULL && oop->klass() == SystemDictionary::String_klass(), "only strings are supported");
-  return (oop->size() + java_lang_String::value(oop)->size()) * HeapWordSize;
+  if (obj == NULL) {
+    return 0;
+  } else if (obj->klass() == SystemDictionary::String_klass()) {
+    return (obj->size() + java_lang_String::value(obj)->size()) * HeapWordSize;
+  } else {
+    return obj->size();
+  }
 }
 
 // Dump footprint and bucket length statistics
 //
 // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to

@@ -335,10 +347,25 @@
   }
   _buckets = (HashtableBucket<F>*)memcpy(*top, _buckets, len);
   *top += len;
 }
 
+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);
+         e != NULL; e = e->next()) {
+      count++;
+      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>));
+}
 
 #ifndef PRODUCT
 
 template <class T, MEMFLAGS F> void Hashtable<T, F>::print() {
   ResourceMark rm;
< prev index next >