src/hotspot/share/utilities/hashtable.cpp
changeset 47774 69c081ca110a
parent 47634 6a0c42c40cd1
child 48794 ea0d0781c63c
--- a/src/hotspot/share/utilities/hashtable.cpp	Thu Nov 02 18:44:44 2017 +0300
+++ b/src/hotspot/share/utilities/hashtable.cpp	Thu Nov 02 11:00:34 2017 -0500
@@ -264,6 +264,49 @@
   }
 }
 
+template <MEMFLAGS F> bool BasicHashtable<F>::resize(int new_size) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+
+  // Allocate new buckets
+  HashtableBucket<F>* buckets_new = NEW_C_HEAP_ARRAY2_RETURN_NULL(HashtableBucket<F>, new_size, F, CURRENT_PC);
+  if (buckets_new == NULL) {
+    return false;
+  }
+
+  // Clear the new buckets
+  for (int i = 0; i < new_size; i++) {
+    buckets_new[i].clear();
+  }
+
+  int table_size_old = _table_size;
+  // hash_to_index() uses _table_size, so switch the sizes now
+  _table_size = new_size;
+
+  // Move entries from the old table to a new table
+  for (int index_old = 0; index_old < table_size_old; index_old++) {
+    for (BasicHashtableEntry<F>* p = _buckets[index_old].get_entry(); p != NULL; ) {
+      BasicHashtableEntry<F>* next = p->next();
+      bool keep_shared = p->is_shared();
+      int index_new = hash_to_index(p->hash());
+
+      p->set_next(buckets_new[index_new].get_entry());
+      buckets_new[index_new].set_entry(p);
+
+      if (keep_shared) {
+        p->set_shared();
+      }
+      p = next;
+    }
+  }
+
+  // The old backets now can be released
+  BasicHashtable<F>::free_buckets();
+
+  // Switch to the new storage
+  _buckets = buckets_new;
+
+  return true;
+}
 
 // Dump footprint and bucket length statistics
 //