325 int index_for(Symbol* name, ClassLoaderData* loader_data) { |
325 int index_for(Symbol* name, ClassLoaderData* loader_data) { |
326 return this->hash_to_index(compute_hash(name, loader_data)); |
326 return this->hash_to_index(compute_hash(name, loader_data)); |
327 } |
327 } |
328 }; |
328 }; |
329 |
329 |
330 |
|
331 /* |
|
332 * Usage of GenericHashtable: |
|
333 * |
|
334 * class X : public GenericHashtableEntry<X, ResourceObj> { |
|
335 * |
|
336 * // Implement virtual functions in class X |
|
337 * bool equals(X* sig) const; |
|
338 * uintptr_t hash() const; |
|
339 * }; |
|
340 * |
|
341 * void foo() { |
|
342 * GenericHashtable<X, ResourceObj>* table = new GenericHashtable<X, ResourceObj>(11027, false); |
|
343 * |
|
344 * X* elem = new X(); |
|
345 * table->add(elem); |
|
346 * table->contains(elem); |
|
347 * } |
|
348 * |
|
349 * You can choose other allocation types as well. For example, to store the hashtable to a |
|
350 * particular region (CHeapObj<type>) simply replace ResourceObj with the desired type: |
|
351 * |
|
352 * class X : public GenericHashtableEntry<X, CHeapObj<mtCode> > { ... }; |
|
353 * |
|
354 * To make the destructor (and remove) of the hashtable work: |
|
355 * 1) override the delete operator of X |
|
356 * 2) provide a destructor of the X |
|
357 * |
|
358 * You may also find it convenient to override the new operator. |
|
359 * |
|
360 * If you use this templates do not forget to add an explicit initialization |
|
361 * (at the end of hashtable.cpp). |
|
362 * |
|
363 * template class GenericHashtable<X, ResourceObj>; |
|
364 */ |
|
365 template <class T, class M> class GenericHashtableEntry : public M { |
|
366 private: |
|
367 T* _next; |
|
368 T* _prev; |
|
369 public: |
|
370 // Must be implemented by subclass. |
|
371 virtual uintptr_t key() const = 0; |
|
372 virtual bool equals(T* other) const = 0; |
|
373 |
|
374 T* next() const { return _next; } |
|
375 T* prev() const { return _prev; } |
|
376 void set_next(T* item) { _next = item; } |
|
377 void set_prev(T* item) { _prev = item; } |
|
378 |
|
379 // Constructor and destructor |
|
380 GenericHashtableEntry() : _next(NULL), _prev(NULL) { }; |
|
381 virtual ~GenericHashtableEntry() {}; |
|
382 }; |
|
383 |
|
384 template <class T, class M> class GenericHashtable : public M { |
|
385 private: |
|
386 T** _items; |
|
387 int _size; |
|
388 bool _C_heap; |
|
389 MEMFLAGS _memflag; |
|
390 |
|
391 // Accessor methods |
|
392 T* head (int idx) const { return _items[idx]; } |
|
393 void set_head(T* item, int idx) { _items[idx] = item; } |
|
394 int index (T* item) { assert(item != NULL, "missing null check"); return item->key() % size(); } |
|
395 |
|
396 // Helper function |
|
397 T* contains_impl(T* item, int idx); |
|
398 |
|
399 DEBUG_ONLY(int _num_items;) |
|
400 public: |
|
401 GenericHashtable(int size, bool C_heap = false, MEMFLAGS memflag = mtNone); |
|
402 ~GenericHashtable(); |
|
403 T* contains(T* match_item); |
|
404 T* remove (T* match_item); |
|
405 bool add (T* item); |
|
406 |
|
407 |
|
408 bool on_C_heap() const { return _C_heap; } |
|
409 int size() const { return _size; } |
|
410 }; |
|
411 |
|
412 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP |
330 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP |