comparison src/share/vm/utilities/hashtable.hpp @ 2177:3582bf76420e

6990754: Use native memory and reference counting to implement SymbolTable Summary: move symbols from permgen into C heap and reference count them Reviewed-by: never, acorn, jmasa, stefank
author coleenp
date Thu, 27 Jan 2011 16:11:27 -0800
parents f95d63e2154a
children 3adec115d40d
comparison
equal deleted inserted replaced
2176:27e4ea99855d 2177:3582bf76420e
25 #ifndef SHARE_VM_UTILITIES_HASHTABLE_HPP 25 #ifndef SHARE_VM_UTILITIES_HASHTABLE_HPP
26 #define SHARE_VM_UTILITIES_HASHTABLE_HPP 26 #define SHARE_VM_UTILITIES_HASHTABLE_HPP
27 27
28 #include "memory/allocation.hpp" 28 #include "memory/allocation.hpp"
29 #include "oops/oop.hpp" 29 #include "oops/oop.hpp"
30 #include "oops/symbolOop.hpp" 30 #include "oops/symbol.hpp"
31 #include "runtime/handles.hpp" 31 #include "runtime/handles.hpp"
32 32
33 // This is a generic hashtable, designed to be used for the symbol 33 // This is a generic hashtable, designed to be used for the symbol
34 // and string tables. 34 // and string tables.
35 // 35 //
94 } 94 }
95 }; 95 };
96 96
97 97
98 98
99 class HashtableEntry : public BasicHashtableEntry { 99 template <class T> class HashtableEntry : public BasicHashtableEntry {
100 friend class VMStructs; 100 friend class VMStructs;
101 private: 101 private:
102 oop _literal; // ref to item in table. 102 T _literal; // ref to item in table.
103 103
104 public: 104 public:
105 // Literal 105 // Literal
106 oop literal() const { return _literal; } 106 T literal() const { return _literal; }
107 oop* literal_addr() { return &_literal; } 107 T* literal_addr() { return &_literal; }
108 void set_literal(oop s) { _literal = s; } 108 void set_literal(T s) { _literal = s; }
109 109
110 HashtableEntry* next() const { 110 HashtableEntry* next() const {
111 return (HashtableEntry*)BasicHashtableEntry::next(); 111 return (HashtableEntry*)BasicHashtableEntry::next();
112 } 112 }
113 HashtableEntry** next_addr() { 113 HashtableEntry** next_addr() {
156 return h; 156 return h;
157 } 157 }
158 158
159 // Reverse the order of elements in each of the buckets. 159 // Reverse the order of elements in each of the buckets.
160 void reverse(); 160 void reverse();
161
162 static unsigned int hash_symbol(const char* s, int len);
161 163
162 private: 164 private:
163 // Instance variables 165 // Instance variables
164 int _table_size; 166 int _table_size;
165 HashtableBucket* _buckets; 167 HashtableBucket* _buckets;
203 205
204 void verify() PRODUCT_RETURN; 206 void verify() PRODUCT_RETURN;
205 }; 207 };
206 208
207 209
208 class Hashtable : public BasicHashtable { 210 template <class T> class Hashtable : public BasicHashtable {
209 friend class VMStructs; 211 friend class VMStructs;
210 212
211 public: 213 public:
212 Hashtable(int table_size, int entry_size) 214 Hashtable(int table_size, int entry_size)
213 : BasicHashtable(table_size, entry_size) { } 215 : BasicHashtable(table_size, entry_size) { }
214 216
215 Hashtable(int table_size, int entry_size, 217 Hashtable(int table_size, int entry_size,
216 HashtableBucket* buckets, int number_of_entries) 218 HashtableBucket* buckets, int number_of_entries)
217 : BasicHashtable(table_size, entry_size, buckets, number_of_entries) { } 219 : BasicHashtable(table_size, entry_size, buckets, number_of_entries) { }
218 220
219 // Invoke "f->do_oop" on the locations of all oops in the table.
220 void oops_do(OopClosure* f);
221
222 // Debugging 221 // Debugging
223 void print() PRODUCT_RETURN; 222 void print() PRODUCT_RETURN;
224
225 // GC support
226 // Delete pointers to otherwise-unreachable objects.
227 void unlink(BoolObjectClosure* cl);
228 223
229 // Reverse the order of elements in each of the buckets. Hashtable 224 // Reverse the order of elements in each of the buckets. Hashtable
230 // entries which refer to objects at a lower address than 'boundary' 225 // entries which refer to objects at a lower address than 'boundary'
231 // are separated from those which refer to objects at higher 226 // are separated from those which refer to objects at higher
232 // addresses, and appear first in the list. 227 // addresses, and appear first in the list.
233 void reverse(void* boundary = NULL); 228 void reverse(void* boundary = NULL);
234 229
235 protected: 230 protected:
236 231
237 static unsigned int hash_symbol(const char* s, int len); 232 unsigned int compute_hash(Symbol* name) {
238
239 unsigned int compute_hash(symbolHandle name) {
240 return (unsigned int) name->identity_hash(); 233 return (unsigned int) name->identity_hash();
241 } 234 }
242 235
243 int index_for(symbolHandle name) { 236 int index_for(Symbol* name) {
244 return hash_to_index(compute_hash(name)); 237 return hash_to_index(compute_hash(name));
245 } 238 }
246 239
247 // Table entry management 240 // Table entry management
248 HashtableEntry* new_entry(unsigned int hashValue, oop obj); 241 HashtableEntry<T>* new_entry(unsigned int hashValue, T obj);
249 242
250 // The following method is MT-safe and may be used with caution. 243 // The following method is MT-safe and may be used with caution.
251 HashtableEntry* bucket(int i) { 244 HashtableEntry<T>* bucket(int i) {
252 return (HashtableEntry*)BasicHashtable::bucket(i); 245 return (HashtableEntry<T>*)BasicHashtable::bucket(i);
253 } 246 }
254 247
255 // The following method is not MT-safe and must be done under lock. 248 // The following method is not MT-safe and must be done under lock.
256 HashtableEntry** bucket_addr(int i) { 249 HashtableEntry<T>** bucket_addr(int i) {
257 return (HashtableEntry**)BasicHashtable::bucket_addr(i); 250 return (HashtableEntry<T>**)BasicHashtable::bucket_addr(i);
258 } 251 }
259 }; 252 };
260 253
261 254
262 // Verions of hashtable where two handles are used to compute the index. 255 // Verions of hashtable where two handles are used to compute the index.
263 256
264 class TwoOopHashtable : public Hashtable { 257 template <class T> class TwoOopHashtable : public Hashtable<T> {
265 friend class VMStructs; 258 friend class VMStructs;
266 protected: 259 protected:
267 TwoOopHashtable(int table_size, int entry_size) 260 TwoOopHashtable(int table_size, int entry_size)
268 : Hashtable(table_size, entry_size) {} 261 : Hashtable<T>(table_size, entry_size) {}
269 262
270 TwoOopHashtable(int table_size, int entry_size, HashtableBucket* t, 263 TwoOopHashtable(int table_size, int entry_size, HashtableBucket* t,
271 int number_of_entries) 264 int number_of_entries)
272 : Hashtable(table_size, entry_size, t, number_of_entries) {} 265 : Hashtable<T>(table_size, entry_size, t, number_of_entries) {}
273 266
274 public: 267 public:
275 unsigned int compute_hash(symbolHandle name, Handle loader) { 268 unsigned int compute_hash(Symbol* name, Handle loader) {
276 // Be careful with identity_hash(), it can safepoint and if this 269 // Be careful with identity_hash(), it can safepoint and if this
277 // were one expression, the compiler could choose to unhandle each 270 // were one expression, the compiler could choose to unhandle each
278 // oop before calling identity_hash() for either of them. If the first 271 // oop before calling identity_hash() for either of them. If the first
279 // causes a GC, the next would fail. 272 // causes a GC, the next would fail.
280 unsigned int name_hash = name->identity_hash(); 273 unsigned int name_hash = name->identity_hash();
281 unsigned int loader_hash = loader.is_null() ? 0 : loader->identity_hash(); 274 unsigned int loader_hash = loader.is_null() ? 0 : loader->identity_hash();
282 return name_hash ^ loader_hash; 275 return name_hash ^ loader_hash;
283 } 276 }
284 277
285 int index_for(symbolHandle name, Handle loader) { 278 int index_for(Symbol* name, Handle loader) {
286 return hash_to_index(compute_hash(name, loader)); 279 return hash_to_index(compute_hash(name, loader));
287 } 280 }
288 }; 281 };
289 282
290 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP 283 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP