1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/utilities/resourceHash.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,138 @@ 1.4 +/* 1.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_UTILITIES_RESOURCEHASH_HPP 1.29 +#define SHARE_VM_UTILITIES_RESOURCEHASH_HPP 1.30 + 1.31 +#include "memory/allocation.hpp" 1.32 +#include "utilities/top.hpp" 1.33 + 1.34 +template<typename K> struct ResourceHashtableFns { 1.35 + typedef unsigned (*hash_fn)(K const&); 1.36 + typedef bool (*equals_fn)(K const&, K const&); 1.37 +}; 1.38 + 1.39 +template<typename K> unsigned primitive_hash(const K& k) { 1.40 + unsigned hash = (unsigned)((uintptr_t)k); 1.41 + return hash ^ (hash > 3); // just in case we're dealing with aligned ptrs 1.42 +} 1.43 + 1.44 +template<typename K> bool primitive_equals(const K& k0, const K& k1) { 1.45 + return k0 == k1; 1.46 +} 1.47 + 1.48 +template< 1.49 + typename K, typename V, 1.50 + // xlC does not compile this: 1.51 + // http://stackoverflow.com/questions/8532961/template-argument-of-type-that-is-defined-by-inner-typedef-from-other-template-c 1.52 + //typename ResourceHashtableFns<K>::hash_fn HASH = primitive_hash<K>, 1.53 + //typename ResourceHashtableFns<K>::equals_fn EQUALS = primitive_equals<K>, 1.54 + unsigned (*HASH) (K const&) = primitive_hash<K>, 1.55 + bool (*EQUALS)(K const&, K const&) = primitive_equals<K>, 1.56 + unsigned SIZE = 256 1.57 + > 1.58 +class ResourceHashtable : public ResourceObj { 1.59 + private: 1.60 + 1.61 + class Node : public ResourceObj { 1.62 + public: 1.63 + unsigned _hash; 1.64 + K _key; 1.65 + V _value; 1.66 + Node* _next; 1.67 + 1.68 + Node(unsigned hash, K const& key, V const& value) : 1.69 + _hash(hash), _key(key), _value(value), _next(NULL) {} 1.70 + }; 1.71 + 1.72 + Node* _table[SIZE]; 1.73 + 1.74 + // Returns a pointer to where the node where the value would reside if 1.75 + // it's in the table. 1.76 + Node** lookup_node(unsigned hash, K const& key) { 1.77 + unsigned index = hash % SIZE; 1.78 + Node** ptr = &_table[index]; 1.79 + while (*ptr != NULL) { 1.80 + Node* node = *ptr; 1.81 + if (node->_hash == hash && EQUALS(key, node->_key)) { 1.82 + break; 1.83 + } 1.84 + ptr = &(node->_next); 1.85 + } 1.86 + return ptr; 1.87 + } 1.88 + 1.89 + Node const** lookup_node(unsigned hash, K const& key) const { 1.90 + return const_cast<Node const**>( 1.91 + const_cast<ResourceHashtable*>(this)->lookup_node(hash, key)); 1.92 + } 1.93 + 1.94 + public: 1.95 + ResourceHashtable() { memset(_table, 0, SIZE * sizeof(Node*)); } 1.96 + 1.97 + bool contains(K const& key) const { 1.98 + return get(key) != NULL; 1.99 + } 1.100 + 1.101 + V* get(K const& key) const { 1.102 + unsigned hv = HASH(key); 1.103 + Node const** ptr = lookup_node(hv, key); 1.104 + if (*ptr != NULL) { 1.105 + return const_cast<V*>(&(*ptr)->_value); 1.106 + } else { 1.107 + return NULL; 1.108 + } 1.109 + } 1.110 + 1.111 + // Inserts or replaces a value in the table 1.112 + void put(K const& key, V const& value) { 1.113 + unsigned hv = HASH(key); 1.114 + Node** ptr = lookup_node(hv, key); 1.115 + if (*ptr != NULL) { 1.116 + (*ptr)->_value = value; 1.117 + } else { 1.118 + *ptr = new Node(hv, key, value); 1.119 + } 1.120 + } 1.121 + 1.122 + // ITER contains bool do_entry(K const&, V const&), which will be 1.123 + // called for each entry in the table. If do_entry() returns false, 1.124 + // the iteration is cancelled. 1.125 + template<class ITER> 1.126 + void iterate(ITER* iter) const { 1.127 + Node* const* bucket = _table; 1.128 + while (bucket < &_table[SIZE]) { 1.129 + Node* node = *bucket; 1.130 + while (node != NULL) { 1.131 + bool cont = iter->do_entry(node->_key, node->_value); 1.132 + if (!cont) { return; } 1.133 + node = node->_next; 1.134 + } 1.135 + ++bucket; 1.136 + } 1.137 + } 1.138 +}; 1.139 + 1.140 + 1.141 +#endif // SHARE_VM_UTILITIES_RESOURCEHASH_HPP