< prev index next >

src/hotspot/share/utilities/resourceHash.hpp

Print this page

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -39,10 +39,14 @@
 
 template<typename K> bool primitive_equals(const K& k0, const K& k1) {
   return k0 == k1;
 }
 
+enum {
+  CONFIGURABLE_SIZE = 0
+};
+
 template<
     typename K, typename V,
     // xlC does not compile this:
     // http://stackoverflow.com/questions/8532961/template-argument-of-type-that-is-defined-by-inner-typedef-from-other-template-c
     //typename ResourceHashtableFns<K>::hash_fn   HASH   = primitive_hash<K>,

@@ -65,17 +69,20 @@
 
     Node(unsigned hash, K const& key, V const& value) :
         _hash(hash), _key(key), _value(value), _next(NULL) {}
   };
 
-  Node* _table[SIZE];
+  Node* _static_table[SIZE == 0 ? 1 : SIZE];
+  unsigned _configured_table_size;
+  Node** _configured_table;
 
   // Returns a pointer to where the node where the value would reside if
   // it's in the table.
   Node** lookup_node(unsigned hash, K const& key) {
-    unsigned index = hash % SIZE;
-    Node** ptr = &_table[index];
+    unsigned index = hash % size();
+    Node** table = get_table();
+    Node** ptr = &table[index];
     while (*ptr != NULL) {
       Node* node = *ptr;
       if (node->_hash == hash && EQUALS(key, node->_key)) {
         break;
       }

@@ -88,24 +95,54 @@
     return const_cast<Node const**>(
         const_cast<ResourceHashtable*>(this)->lookup_node(hash, key));
   }
 
  public:
-  ResourceHashtable() { memset(_table, 0, SIZE * sizeof(Node*)); }
+  ResourceHashtable() {
+    assert(SIZE != CONFIGURABLE_SIZE, "must be");
+    memset(_static_table, 0, SIZE * sizeof(Node*));
+    _configured_table = NULL;
+  }
+
+  ResourceHashtable(unsigned configured_table_size) : _configured_table_size(configured_table_size) {
+    assert(SIZE == CONFIGURABLE_SIZE, "must be");
+    _configured_table = (Node**)operator new(size() * sizeof(Node*), ALLOC_TYPE, MEM_TYPE);
+    memset(_configured_table, 0, size() * sizeof(Node*));
+  }
+
+  ALWAYSINLINE unsigned size() const {
+    if (SIZE != CONFIGURABLE_SIZE) {
+      return SIZE;
+    } else {
+      return _configured_table_size;
+    }
+  }
+
+  ALWAYSINLINE Node** get_table() const {
+    if (SIZE != CONFIGURABLE_SIZE) {
+      return (Node**)(&_static_table[0]);
+    } else {
+      return _configured_table;
+    }
+  }
 
   ~ResourceHashtable() {
     if (ALLOC_TYPE == C_HEAP) {
-      Node* const* bucket = _table;
-      while (bucket < &_table[SIZE]) {
+      Node** table = get_table();
+      Node* const* bucket = table;
+      while (bucket < &table[size()]) {
         Node* node = *bucket;
         while (node != NULL) {
           Node* cur = node;
           node = node->_next;
           delete cur;
         }
         ++bucket;
       }
+      if (_configured_table != NULL) {
+        FreeHeap((void*)_configured_table);
+      }
     }
   }
 
   bool contains(K const& key) const {
     return get(key) != NULL;

@@ -156,12 +193,13 @@
   // ITER contains bool do_entry(K const&, V const&), which will be
   // called for each entry in the table.  If do_entry() returns false,
   // the iteration is cancelled.
   template<class ITER>
   void iterate(ITER* iter) const {
-    Node* const* bucket = _table;
-    while (bucket < &_table[SIZE]) {
+    Node** table = get_table();
+    Node* const* bucket = table;
+    while (bucket < &table[size()]) {
       Node* node = *bucket;
       while (node != NULL) {
         bool cont = iter->do_entry(node->_key, node->_value);
         if (!cont) { return; }
         node = node->_next;
< prev index next >