12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_UTILITIES_HASHTABLE_HPP
26 #define SHARE_VM_UTILITIES_HASHTABLE_HPP
27
28 #include "memory/allocation.hpp"
29 #include "oops/oop.hpp"
30 #include "oops/symbol.hpp"
31 #include "runtime/handles.hpp"
32
33 // This is a generic hashtable, designed to be used for the symbol
34 // and string tables.
35 //
36 // It is implemented as an open hash table with a fixed number of buckets.
37 //
38 // %note:
39 // - TableEntrys are allocated in blocks to reduce the space overhead.
40
41
42
43 template <MEMFLAGS F> class BasicHashtableEntry : public CHeapObj<F> {
44 friend class VMStructs;
45 private:
46 unsigned int _hash; // 32-bit hash for item
47
48 // Link to next element in the linked list for this bucket. EXCEPT
49 // bit 0 set indicates that this entry is shared and must not be
50 // unlinked from the table. Bit 0 is set during the dumping of the
51 // archive. Since shared entries are immutable, _next fields in the
128 void clear() { _entry = NULL; }
129
130 // The following methods use order access methods to avoid race
131 // conditions in multiprocessor systems.
132 BasicHashtableEntry<F>* get_entry() const;
133 void set_entry(BasicHashtableEntry<F>* l);
134
135 // The following method is not MT-safe and must be done under lock.
136 BasicHashtableEntry<F>** entry_addr() { return &_entry; }
137
138 };
139
140
141 template <MEMFLAGS F> class BasicHashtable : public CHeapObj<F> {
142 friend class VMStructs;
143
144 public:
145 BasicHashtable(int table_size, int entry_size);
146 BasicHashtable(int table_size, int entry_size,
147 HashtableBucket<F>* buckets, int number_of_entries);
148
149 // Bucket handling
150 int hash_to_index(unsigned int full_hash) const {
151 int h = full_hash % _table_size;
152 assert(h >= 0 && h < _table_size, "Illegal hash value");
153 return h;
154 }
155
156 private:
157 // Instance variables
158 int _table_size;
159 HashtableBucket<F>* _buckets;
160 BasicHashtableEntry<F>* volatile _free_list;
161 char* _first_free_entry;
162 char* _end_block;
163 int _entry_size;
164 volatile int _number_of_entries;
165
166 protected:
167
168 void initialize(int table_size, int entry_size, int number_of_entries);
169
170 // Accessor
171 int entry_size() const { return _entry_size; }
172
173 // The following method is MT-safe and may be used with caution.
174 BasicHashtableEntry<F>* bucket(int i) const;
175
176 // The following method is not MT-safe and must be done under lock.
177 BasicHashtableEntry<F>** bucket_addr(int i) { return _buckets[i].entry_addr(); }
178
179 // Attempt to get an entry from the free list
180 BasicHashtableEntry<F>* new_entry_free_list();
181
182 // Table entry management
183 BasicHashtableEntry<F>* new_entry(unsigned int hashValue);
184
274
275 // Table entry management
276 HashtableEntry<T, F>* new_entry(unsigned int hashValue, T obj);
277 // Don't create and use freelist of HashtableEntry.
278 HashtableEntry<T, F>* allocate_new_entry(unsigned int hashValue, T obj);
279
280 // The following method is MT-safe and may be used with caution.
281 HashtableEntry<T, F>* bucket(int i) const {
282 return (HashtableEntry<T, F>*)BasicHashtable<F>::bucket(i);
283 }
284
285 // The following method is not MT-safe and must be done under lock.
286 HashtableEntry<T, F>** bucket_addr(int i) {
287 return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
288 }
289 };
290
291 // A subclass of BasicHashtable that allows you to do a simple K -> V mapping
292 // without using tons of boilerplate code.
293 template<
294 typename K, typename V,
295 MEMFLAGS F = mtInternal,
296 unsigned (*HASH) (K const&) = primitive_hash<K>,
297 bool (*EQUALS)(K const&, K const&) = primitive_equals<K>
298 >
299 class KVHashtable : public BasicHashtable<F> {
300 class KVHashtableEntry : public BasicHashtableEntry<F> {
301 public:
302 K _key;
303 V _value;
304 KVHashtableEntry* next() {
305 return (KVHashtableEntry*)BasicHashtableEntry<F>::next();
306 }
307 };
308
309 protected:
310 KVHashtableEntry* bucket(int i) const {
311 return (KVHashtableEntry*)BasicHashtable<F>::bucket(i);
312 }
313
314 KVHashtableEntry* new_entry(unsigned int hashValue, K key, V value) {
315 KVHashtableEntry* entry = (KVHashtableEntry*)BasicHashtable<F>::new_entry(hashValue);
|
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_UTILITIES_HASHTABLE_HPP
26 #define SHARE_VM_UTILITIES_HASHTABLE_HPP
27
28 #include "memory/allocation.hpp"
29 #include "oops/oop.hpp"
30 #include "oops/symbol.hpp"
31 #include "runtime/handles.hpp"
32 #include "utilities/growableArray.hpp"
33
34 // This is a generic hashtable, designed to be used for the symbol
35 // and string tables.
36 //
37 // It is implemented as an open hash table with a fixed number of buckets.
38 //
39 // %note:
40 // - TableEntrys are allocated in blocks to reduce the space overhead.
41
42
43
44 template <MEMFLAGS F> class BasicHashtableEntry : public CHeapObj<F> {
45 friend class VMStructs;
46 private:
47 unsigned int _hash; // 32-bit hash for item
48
49 // Link to next element in the linked list for this bucket. EXCEPT
50 // bit 0 set indicates that this entry is shared and must not be
51 // unlinked from the table. Bit 0 is set during the dumping of the
52 // archive. Since shared entries are immutable, _next fields in the
129 void clear() { _entry = NULL; }
130
131 // The following methods use order access methods to avoid race
132 // conditions in multiprocessor systems.
133 BasicHashtableEntry<F>* get_entry() const;
134 void set_entry(BasicHashtableEntry<F>* l);
135
136 // The following method is not MT-safe and must be done under lock.
137 BasicHashtableEntry<F>** entry_addr() { return &_entry; }
138
139 };
140
141
142 template <MEMFLAGS F> class BasicHashtable : public CHeapObj<F> {
143 friend class VMStructs;
144
145 public:
146 BasicHashtable(int table_size, int entry_size);
147 BasicHashtable(int table_size, int entry_size,
148 HashtableBucket<F>* buckets, int number_of_entries);
149 ~BasicHashtable();
150
151 // Bucket handling
152 int hash_to_index(unsigned int full_hash) const {
153 int h = full_hash % _table_size;
154 assert(h >= 0 && h < _table_size, "Illegal hash value");
155 return h;
156 }
157
158 private:
159 // Instance variables
160 int _table_size;
161 HashtableBucket<F>* _buckets;
162 BasicHashtableEntry<F>* volatile _free_list;
163 char* _first_free_entry;
164 char* _end_block;
165 int _entry_size;
166 volatile int _number_of_entries;
167 GrowableArray<char*>* _entry_blocks;
168
169 protected:
170
171 void initialize(int table_size, int entry_size, int number_of_entries);
172
173 // Accessor
174 int entry_size() const { return _entry_size; }
175
176 // The following method is MT-safe and may be used with caution.
177 BasicHashtableEntry<F>* bucket(int i) const;
178
179 // The following method is not MT-safe and must be done under lock.
180 BasicHashtableEntry<F>** bucket_addr(int i) { return _buckets[i].entry_addr(); }
181
182 // Attempt to get an entry from the free list
183 BasicHashtableEntry<F>* new_entry_free_list();
184
185 // Table entry management
186 BasicHashtableEntry<F>* new_entry(unsigned int hashValue);
187
277
278 // Table entry management
279 HashtableEntry<T, F>* new_entry(unsigned int hashValue, T obj);
280 // Don't create and use freelist of HashtableEntry.
281 HashtableEntry<T, F>* allocate_new_entry(unsigned int hashValue, T obj);
282
283 // The following method is MT-safe and may be used with caution.
284 HashtableEntry<T, F>* bucket(int i) const {
285 return (HashtableEntry<T, F>*)BasicHashtable<F>::bucket(i);
286 }
287
288 // The following method is not MT-safe and must be done under lock.
289 HashtableEntry<T, F>** bucket_addr(int i) {
290 return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
291 }
292 };
293
294 // A subclass of BasicHashtable that allows you to do a simple K -> V mapping
295 // without using tons of boilerplate code.
296 template<
297 typename K, typename V, MEMFLAGS F,
298 unsigned (*HASH) (K const&) = primitive_hash<K>,
299 bool (*EQUALS)(K const&, K const&) = primitive_equals<K>
300 >
301 class KVHashtable : public BasicHashtable<F> {
302 class KVHashtableEntry : public BasicHashtableEntry<F> {
303 public:
304 K _key;
305 V _value;
306 KVHashtableEntry* next() {
307 return (KVHashtableEntry*)BasicHashtableEntry<F>::next();
308 }
309 };
310
311 protected:
312 KVHashtableEntry* bucket(int i) const {
313 return (KVHashtableEntry*)BasicHashtable<F>::bucket(i);
314 }
315
316 KVHashtableEntry* new_entry(unsigned int hashValue, K key, V value) {
317 KVHashtableEntry* entry = (KVHashtableEntry*)BasicHashtable<F>::new_entry(hashValue);
|