hotspot/src/share/vm/utilities/hashtable.hpp
changeset 8076 96d498ec7ae1
parent 7397 5b173b4ca846
child 8310 d7c285113f48
equal deleted inserted replaced
8075:582dd25571b2 8076:96d498ec7ae1
    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