310 311 TwoOopHashtable(int table_size, int entry_size, HashtableBucket<F>* t, 312 int number_of_entries) 313 : Hashtable<T, F>(table_size, entry_size, t, number_of_entries) {} 314 315 public: 316 unsigned int compute_hash(Symbol* name, ClassLoaderData* loader_data) { 317 unsigned int name_hash = name->identity_hash(); 318 // loader is null with CDS 319 assert(loader_data != NULL || UseSharedSpaces || DumpSharedSpaces, 320 "only allowed with shared spaces"); 321 unsigned int loader_hash = loader_data == NULL ? 0 : loader_data->identity_hash(); 322 return name_hash ^ loader_hash; 323 } 324 325 int index_for(Symbol* name, ClassLoaderData* loader_data) { 326 return this->hash_to_index(compute_hash(name, loader_data)); 327 } 328 }; 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 | 310 311 TwoOopHashtable(int table_size, int entry_size, HashtableBucket<F>* t, 312 int number_of_entries) 313 : Hashtable<T, F>(table_size, entry_size, t, number_of_entries) {} 314 315 public: 316 unsigned int compute_hash(Symbol* name, ClassLoaderData* loader_data) { 317 unsigned int name_hash = name->identity_hash(); 318 // loader is null with CDS 319 assert(loader_data != NULL || UseSharedSpaces || DumpSharedSpaces, 320 "only allowed with shared spaces"); 321 unsigned int loader_hash = loader_data == NULL ? 0 : loader_data->identity_hash(); 322 return name_hash ^ loader_hash; 323 } 324 325 int index_for(Symbol* name, ClassLoaderData* loader_data) { 326 return this->hash_to_index(compute_hash(name, loader_data)); 327 } 328 }; 329 330 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP |