hotspot/src/share/vm/utilities/hashtable.cpp
changeset 8076 96d498ec7ae1
parent 7397 5b173b4ca846
child 8921 14bfe81f2a9d
equal deleted inserted replaced
8075:582dd25571b2 8076:96d498ec7ae1
    29 #include "runtime/safepoint.hpp"
    29 #include "runtime/safepoint.hpp"
    30 #include "utilities/dtrace.hpp"
    30 #include "utilities/dtrace.hpp"
    31 #include "utilities/hashtable.hpp"
    31 #include "utilities/hashtable.hpp"
    32 #include "utilities/hashtable.inline.hpp"
    32 #include "utilities/hashtable.inline.hpp"
    33 
    33 
       
    34 
    34 HS_DTRACE_PROBE_DECL4(hs_private, hashtable__new_entry,
    35 HS_DTRACE_PROBE_DECL4(hs_private, hashtable__new_entry,
    35   void*, unsigned int, oop, void*);
    36   void*, unsigned int, void*, void*);
    36 
    37 
    37 // This is a generic hashtable, designed to be used for the symbol
    38 // This is a generic hashtable, designed to be used for the symbol
    38 // and string tables.
    39 // and string tables.
    39 //
    40 //
    40 // It is implemented as an open hash table with a fixed number of buckets.
    41 // It is implemented as an open hash table with a fixed number of buckets.
    65   entry->set_hash(hashValue);
    66   entry->set_hash(hashValue);
    66   return entry;
    67   return entry;
    67 }
    68 }
    68 
    69 
    69 
    70 
    70 HashtableEntry* Hashtable::new_entry(unsigned int hashValue, oop obj) {
    71 template <class T> HashtableEntry<T>* Hashtable<T>::new_entry(unsigned int hashValue, T obj) {
    71   HashtableEntry* entry;
    72   HashtableEntry<T>* entry;
    72 
    73 
    73   entry = (HashtableEntry*)BasicHashtable::new_entry(hashValue);
    74   entry = (HashtableEntry<T>*)BasicHashtable::new_entry(hashValue);
    74   entry->set_literal(obj);   // clears literal string field
    75   entry->set_literal(obj);
    75   HS_DTRACE_PROBE4(hs_private, hashtable__new_entry,
    76   HS_DTRACE_PROBE4(hs_private, hashtable__new_entry,
    76     this, hashValue, obj, entry);
    77     this, hashValue, obj, entry);
    77   return entry;
    78   return entry;
    78 }
       
    79 
       
    80 
       
    81 // GC support
       
    82 
       
    83 void Hashtable::unlink(BoolObjectClosure* is_alive) {
       
    84   // Readers of the table are unlocked, so we should only be removing
       
    85   // entries at a safepoint.
       
    86   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
       
    87   for (int i = 0; i < table_size(); ++i) {
       
    88     for (HashtableEntry** p = bucket_addr(i); *p != NULL; ) {
       
    89       HashtableEntry* entry = *p;
       
    90       if (entry->is_shared()) {
       
    91         break;
       
    92       }
       
    93       assert(entry->literal() != NULL, "just checking");
       
    94       if (is_alive->do_object_b(entry->literal())) {
       
    95         p = entry->next_addr();
       
    96       } else {
       
    97         *p = entry->next();
       
    98         free_entry(entry);
       
    99       }
       
   100     }
       
   101   }
       
   102 }
       
   103 
       
   104 
       
   105 void Hashtable::oops_do(OopClosure* f) {
       
   106   for (int i = 0; i < table_size(); ++i) {
       
   107     HashtableEntry** p = bucket_addr(i);
       
   108     HashtableEntry* entry = bucket(i);
       
   109     while (entry != NULL) {
       
   110       f->do_oop(entry->literal_addr());
       
   111 
       
   112       // Did the closure remove the literal from the table?
       
   113       if (entry->literal() == NULL) {
       
   114         assert(!entry->is_shared(), "immutable hashtable entry?");
       
   115         *p = entry->next();
       
   116         free_entry(entry);
       
   117       } else {
       
   118         p = entry->next_addr();
       
   119       }
       
   120       entry = (HashtableEntry*)HashtableEntry::make_ptr(*p);
       
   121     }
       
   122   }
       
   123 }
    79 }
   124 
    80 
   125 
    81 
   126 // Reverse the order of elements in the hash buckets.
    82 // Reverse the order of elements in the hash buckets.
   127 
    83 
   154   for (i = 0; i < _table_size; ++i) {
   110   for (i = 0; i < _table_size; ++i) {
   155     for (BasicHashtableEntry** p = _buckets[i].entry_addr();
   111     for (BasicHashtableEntry** p = _buckets[i].entry_addr();
   156                               *p != NULL;
   112                               *p != NULL;
   157                                p = (*p)->next_addr()) {
   113                                p = (*p)->next_addr()) {
   158       if (*top + entry_size() > end) {
   114       if (*top + entry_size() > end) {
   159         warning("\nThe shared miscellaneous data space is not large "
   115         report_out_of_shared_space(SharedMiscData);
   160                 "enough to \npreload requested classes.  Use "
       
   161                 "-XX:SharedMiscDataSize= to increase \nthe initial "
       
   162                 "size of the miscellaneous data space.\n");
       
   163         exit(2);
       
   164       }
   116       }
   165       *p = (BasicHashtableEntry*)memcpy(*top, *p, entry_size());
   117       *p = (BasicHashtableEntry*)memcpy(*top, *p, entry_size());
   166       *top += entry_size();
   118       *top += entry_size();
   167     }
   119     }
   168   }
   120   }
   179 
   131 
   180 
   132 
   181 
   133 
   182 // Reverse the order of elements in the hash buckets.
   134 // Reverse the order of elements in the hash buckets.
   183 
   135 
   184 void Hashtable::reverse(void* boundary) {
   136 template <class T> void Hashtable<T>::reverse(void* boundary) {
   185 
   137 
   186   for (int i = 0; i < table_size(); ++i) {
   138   for (int i = 0; i < table_size(); ++i) {
   187     HashtableEntry* high_list = NULL;
   139     HashtableEntry<T>* high_list = NULL;
   188     HashtableEntry* low_list = NULL;
   140     HashtableEntry<T>* low_list = NULL;
   189     HashtableEntry* last_low_entry = NULL;
   141     HashtableEntry<T>* last_low_entry = NULL;
   190     HashtableEntry* p = bucket(i);
   142     HashtableEntry<T>* p = bucket(i);
   191     while (p != NULL) {
   143     while (p != NULL) {
   192       HashtableEntry* next = p->next();
   144       HashtableEntry<T>* next = p->next();
   193       if ((void*)p->literal() >= boundary) {
   145       if ((void*)p->literal() >= boundary) {
   194         p->set_next(high_list);
   146         p->set_next(high_list);
   195         high_list = p;
   147         high_list = p;
   196       } else {
   148       } else {
   197         p->set_next(low_list);
   149         p->set_next(low_list);
   221 
   173 
   222   *(intptr_t*)(*top) = _number_of_entries;
   174   *(intptr_t*)(*top) = _number_of_entries;
   223   *top += sizeof(intptr_t);
   175   *top += sizeof(intptr_t);
   224 
   176 
   225   if (*top + len > end) {
   177   if (*top + len > end) {
   226     warning("\nThe shared miscellaneous data space is not large "
   178     report_out_of_shared_space(SharedMiscData);
   227             "enough to \npreload requested classes.  Use "
       
   228             "-XX:SharedMiscDataSize= to increase \nthe initial "
       
   229             "size of the miscellaneous data space.\n");
       
   230     exit(2);
       
   231   }
   179   }
   232   _buckets = (HashtableBucket*)memcpy(*top, _buckets, len);
   180   _buckets = (HashtableBucket*)memcpy(*top, _buckets, len);
   233   *top += len;
   181   *top += len;
   234 }
   182 }
   235 
   183 
   236 
   184 
   237 #ifndef PRODUCT
   185 #ifndef PRODUCT
   238 
   186 
   239 void Hashtable::print() {
   187 template <class T> void Hashtable<T>::print() {
   240   ResourceMark rm;
   188   ResourceMark rm;
   241 
   189 
   242   for (int i = 0; i < table_size(); i++) {
   190   for (int i = 0; i < table_size(); i++) {
   243     HashtableEntry* entry = bucket(i);
   191     HashtableEntry<T>* entry = bucket(i);
   244     while(entry != NULL) {
   192     while(entry != NULL) {
   245       tty->print("%d : ", i);
   193       tty->print("%d : ", i);
   246       entry->literal()->print();
   194       entry->literal()->print();
   247       tty->cr();
   195       tty->cr();
   248       entry = entry->next();
   196       entry = entry->next();
   275             (double) _lookup_length / _lookup_count, load);
   223             (double) _lookup_length / _lookup_count, load);
   276   }
   224   }
   277 }
   225 }
   278 
   226 
   279 #endif
   227 #endif
       
   228 
       
   229 // Explicitly instantiate these types
       
   230 template class Hashtable<constantPoolOop>;
       
   231 template class Hashtable<Symbol*>;
       
   232 template class Hashtable<klassOop>;
       
   233 template class Hashtable<oop>;
       
   234