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