src/hotspot/share/utilities/hashtable.cpp
changeset 52631 3009ca99de32
parent 52514 f4e3900c8d08
child 52673 61b3b58a1d1d
--- a/src/hotspot/share/utilities/hashtable.cpp	Tue Nov 20 18:36:57 2018 -0800
+++ b/src/hotspot/share/utilities/hashtable.cpp	Tue Nov 20 20:00:15 2018 -0800
@@ -65,6 +65,7 @@
       len = 1 << log2_intptr(len); // round down to power of 2
       assert(len >= _entry_size, "");
       _first_free_entry = NEW_C_HEAP_ARRAY2(char, len, F, CURRENT_PC);
+      _entry_blocks->append(_first_free_entry);
       _end_block = _first_free_entry + len;
     }
     entry = (BasicHashtableEntry<F>*)_first_free_entry;
@@ -86,7 +87,9 @@
 }
 
 // Version of hashtable entry allocation that allocates in the C heap directly.
-// The allocator in blocks is preferable but doesn't have free semantics.
+// The block allocator in BasicHashtable has less fragmentation, but the memory is not freed until
+// the whole table is freed. Use allocate_new_entry() if you want to individually free the memory
+// used by each entry
 template <class T, MEMFLAGS F> HashtableEntry<T, F>* Hashtable<T, F>::allocate_new_entry(unsigned int hashValue, T obj) {
   HashtableEntry<T, F>* entry = (HashtableEntry<T, F>*) NEW_C_HEAP_ARRAY(char, this->entry_size(), F);
 
@@ -203,6 +206,20 @@
   return true;
 }
 
+template <MEMFLAGS F> bool BasicHashtable<F>::maybe_grow(int max_size, int load_factor) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+
+  if (table_size() >= max_size) {
+    return false;
+  }
+  if (number_of_entries() / table_size() > load_factor) {
+    resize(MIN2<int>(table_size() * 2, max_size));
+    return true;
+  } else {
+    return false;
+  }
+}
+
 // Dump footprint and bucket length statistics
 //
 // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to