< 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 >