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 |