283 static juint seed() { return _seed; }
284
285 static int literal_size(Symbol *symbol);
286 static int literal_size(oop oop);
287
288 // The following two are currently not used, but are needed anyway because some
289 // C++ compilers (MacOS and Solaris) force the instantiation of
290 // Hashtable<ConstantPool*, mtClass>::dump_table() even though we never call this function
291 // in the VM code.
292 static int literal_size(ConstantPool *cp) {Unimplemented(); return 0;}
293 static int literal_size(Klass *k) {Unimplemented(); return 0;}
294
295 public:
296 void dump_table(outputStream* st, const char *table_name);
297
298 private:
299 static juint _seed;
300 };
301
302
303 // Verions of hashtable where two handles are used to compute the index.
304
305 template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
306 friend class VMStructs;
307 protected:
308 TwoOopHashtable(int table_size, int entry_size)
309 : Hashtable<T, F>(table_size, entry_size) {}
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
|
283 static juint seed() { return _seed; }
284
285 static int literal_size(Symbol *symbol);
286 static int literal_size(oop oop);
287
288 // The following two are currently not used, but are needed anyway because some
289 // C++ compilers (MacOS and Solaris) force the instantiation of
290 // Hashtable<ConstantPool*, mtClass>::dump_table() even though we never call this function
291 // in the VM code.
292 static int literal_size(ConstantPool *cp) {Unimplemented(); return 0;}
293 static int literal_size(Klass *k) {Unimplemented(); return 0;}
294
295 public:
296 void dump_table(outputStream* st, const char *table_name);
297
298 private:
299 static juint _seed;
300 };
301
302
303 // Versions of hashtable where two handles are used to compute the index.
304
305 template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
306 friend class VMStructs;
307 protected:
308 TwoOopHashtable(int table_size, int entry_size)
309 : Hashtable<T, F>(table_size, entry_size) {}
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 * If you use this templates do not forget to add an explicit initialization
355 * (at the end of hashtable.cpp).
356 *
357 * template class GenericHashtable<X, ResourceObj>;
358 */
359 template <class T, class M> class GenericHashtableEntry : public M {
360 private:
361 T* _next;
362 public:
363 // Must be implemented by subclass
364 virtual uintptr_t hash() const = 0;
365 virtual bool equals(T* other) const = 0;
366
367 T* next() { return _next; }
368 void set_next(T* next) { _next = next; }
369
370 // Constructor and destructor
371 GenericHashtableEntry() : _next(NULL) { };
372 virtual ~GenericHashtableEntry() {};
373 };
374
375 template <class T, class M> class GenericHashtable : public M {
376 private:
377 T** _elements;
378 int _size;
379 T* element_at(int idx) { return _elements[idx]; }
380 void set_element_at(T* element, int idx) { _elements[idx] = element; }
381
382 public:
383 GenericHashtable(int size, bool resource_mark, MEMFLAGS memflag = mtNone);
384 ~GenericHashtable() { Unimplemented(); } // Can be added later, if needed
385 bool add(T* element);
386 bool contains(T* element);
387 bool remove(T* element) { Unimplemented(); return false; }
388 int size() { return _size; }
389 };
390
391 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP
|