hotspot/src/share/vm/utilities/hashtable.cpp
changeset 13087 673ea6efaf18
parent 10739 91935236600e
child 13097 c146b608d91f
--- a/hotspot/src/share/vm/utilities/hashtable.cpp	Mon Jun 11 13:10:14 2012 -0400
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp	Wed Jun 13 19:52:59 2012 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -86,6 +86,55 @@
 }
 
 
+// Check to see if the hashtable is unbalanced.  The caller set a flag to
+// rehash at the next safepoint.  If this bucket is 60 times greater than the
+// expected average bucket length, it's an unbalanced hashtable.
+// This is somewhat an arbitrary heuristic but if one bucket gets to
+// rehash_count which is currently 100, there's probably something wrong.
+
+bool BasicHashtable::check_rehash_table(int count) {
+  assert(table_size() != 0, "underflow");
+  if (count > (((double)number_of_entries()/(double)table_size())*rehash_multiple)) {
+    // Set a flag for the next safepoint, which should be at some guaranteed
+    // safepoint interval.
+    return true;
+  }
+  return false;
+}
+
+// Create a new table and using alternate hash code, populate the new table
+// with the existing elements.   This can be used to change the hash code
+// and could in the future change the size of the table.
+
+template <class T> void Hashtable<T>::move_to(Hashtable<T>* new_table) {
+  int saved_entry_count = number_of_entries();
+
+  // Iterate through the table and create a new entry for the new table
+  for (int i = 0; i < new_table->table_size(); ++i) {
+    for (HashtableEntry<T>* p = bucket(i); p != NULL; ) {
+      HashtableEntry<T>* next = p->next();
+      T string = p->literal();
+      // Use alternate hashing algorithm on the symbol in the first table
+      unsigned int hashValue = new_hash(string);
+      // Get a new index relative to the new table (can also change size)
+      int index = new_table->hash_to_index(hashValue);
+      p->set_hash(hashValue);
+      unlink_entry(p);
+      new_table->add_entry(index, p);
+      p = next;
+    }
+  }
+  // give the new table the free list as well
+  new_table->copy_freelist(this);
+  assert(new_table->number_of_entries() == saved_entry_count, "lost entry on dictionary copy?");
+
+  // Destroy memory used by the buckets in the hashtable.  The memory
+  // for the elements has been used in a new table and is not
+  // destroyed.  The memory reuse will benefit resizing the SystemDictionary
+  // to avoid a memory allocation spike at safepoint.
+  free_buckets();
+}
+
 // Reverse the order of elements in the hash buckets.
 
 void BasicHashtable::reverse() {