src/share/vm/classfile/symbolTable.hpp

Print this page
rev 6680 : 8056084: Refactor Hashtable to allow implementations without rehashing support
Reviewed-by: gziemski, jmasa, brutisso, coleenp, tschatzl


  57 
  58   // Operator= increments reference count.
  59   void operator=(const TempNewSymbol &s) {
  60     //clear();  //FIXME
  61     _temp = s._temp;
  62     if (_temp !=NULL) _temp->increment_refcount();
  63   }
  64 
  65   // Decrement reference counter so it can go away if it's unique
  66   void clear() { if (_temp != NULL)  _temp->decrement_refcount();  _temp = NULL; }
  67 
  68   ~TempNewSymbol() { clear(); }
  69 
  70   // Operators so they can be used like Symbols
  71   Symbol* operator -> () const                   { return _temp; }
  72   bool    operator == (Symbol* o) const          { return _temp == o; }
  73   // Sneaky conversion function
  74   operator Symbol*()                             { return _temp; }
  75 };
  76 
  77 class SymbolTable : public Hashtable<Symbol*, mtSymbol> {
  78   friend class VMStructs;
  79   friend class ClassFileParser;
  80 
  81 private:
  82   // The symbol table
  83   static SymbolTable* _the_table;
  84 
  85   // Set if one bucket is out of balance due to hash algorithm deficiency
  86   static bool _needs_rehashing;
  87 
  88   // For statistics
  89   static int _symbols_removed;
  90   static int _symbols_counted;
  91 
  92   Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F
  93 
  94   // Adding elements
  95   Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue,
  96                     bool c_heap, TRAPS);
  97   bool basic_add(ClassLoaderData* loader_data,
  98                  constantPoolHandle cp, int names_count,
  99                  const char** names, int* lengths, int* cp_indices,
 100                  unsigned int* hashValues, TRAPS);
 101 
 102   static void new_symbols(ClassLoaderData* loader_data,
 103                           constantPoolHandle cp, int names_count,
 104                           const char** name, int* lengths,
 105                           int* cp_indices, unsigned int* hashValues,
 106                           TRAPS) {
 107     add(loader_data, cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
 108   }
 109 
 110   Symbol* lookup(int index, const char* name, int len, unsigned int hash);
 111 
 112   SymbolTable()
 113     : Hashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>)) {}
 114 
 115   SymbolTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
 116     : Hashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>), t,
 117                 number_of_entries) {}
 118 
 119   // Arena for permanent symbols (null class loader) that are never unloaded
 120   static Arena*  _arena;
 121   static Arena* arena() { return _arena; }  // called for statistics
 122 
 123   static void initialize_symbols(int arena_alloc_size = 0);
 124 
 125   static volatile int _parallel_claimed_idx;
 126 
 127   // Release any dead symbols
 128   static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total);
 129 public:
 130   enum {
 131     symbol_alloc_batch_size = 8,
 132     // Pick initial size based on java -version size measurements
 133     symbol_alloc_arena_size = 360*K
 134   };
 135 
 136   // The symbol table


 235 
 236   // Sharing
 237   static void copy_buckets(char** top, char*end) {
 238     the_table()->Hashtable<Symbol*, mtSymbol>::copy_buckets(top, end);
 239   }
 240   static void copy_table(char** top, char*end) {
 241     the_table()->Hashtable<Symbol*, mtSymbol>::copy_table(top, end);
 242   }
 243   static void reverse(void* boundary = NULL) {
 244     the_table()->Hashtable<Symbol*, mtSymbol>::reverse(boundary);
 245   }
 246 
 247   // Rehash the symbol table if it gets out of balance
 248   static void rehash_table();
 249   static bool needs_rehashing()         { return _needs_rehashing; }
 250   // Parallel chunked scanning
 251   static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
 252   static int parallel_claimed_index()        { return _parallel_claimed_idx; }
 253 };
 254 
 255 class StringTable : public Hashtable<oop, mtSymbol> {
 256   friend class VMStructs;
 257 
 258 private:
 259   // The string table
 260   static StringTable* _the_table;
 261 
 262   // Set if one bucket is out of balance due to hash algorithm deficiency
 263   static bool _needs_rehashing;
 264 
 265   // Claimed high water mark for parallel chunked scanning
 266   static volatile int _parallel_claimed_idx;
 267 
 268   static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
 269   oop basic_add(int index, Handle string_or_null, jchar* name, int len,
 270                 unsigned int hashValue, TRAPS);
 271 
 272   oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
 273 
 274   // Apply the give oop closure to the entries to the buckets
 275   // in the range [start_idx, end_idx).
 276   static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx);
 277   // Unlink or apply the give oop closure to the entries to the buckets
 278   // in the range [start_idx, end_idx).
 279   static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
 280 
 281   StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize,
 282                               sizeof (HashtableEntry<oop, mtSymbol>)) {}
 283 
 284   StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
 285     : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t,
 286                      number_of_entries) {}
 287 public:
 288   // The string table
 289   static StringTable* the_table() { return _the_table; }
 290 
 291   // Size of one bucket in the string table.  Used when checking for rollover.
 292   static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); }
 293 
 294   static void create_table() {
 295     assert(_the_table == NULL, "One string table allowed.");
 296     _the_table = new StringTable();
 297   }
 298 
 299   // GC support
 300   //   Delete pointers to otherwise-unreachable objects.
 301   static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) {
 302     int processed = 0;
 303     int removed = 0;
 304     unlink_or_oops_do(cl, f, &processed, &removed);
 305   }




  57 
  58   // Operator= increments reference count.
  59   void operator=(const TempNewSymbol &s) {
  60     //clear();  //FIXME
  61     _temp = s._temp;
  62     if (_temp !=NULL) _temp->increment_refcount();
  63   }
  64 
  65   // Decrement reference counter so it can go away if it's unique
  66   void clear() { if (_temp != NULL)  _temp->decrement_refcount();  _temp = NULL; }
  67 
  68   ~TempNewSymbol() { clear(); }
  69 
  70   // Operators so they can be used like Symbols
  71   Symbol* operator -> () const                   { return _temp; }
  72   bool    operator == (Symbol* o) const          { return _temp == o; }
  73   // Sneaky conversion function
  74   operator Symbol*()                             { return _temp; }
  75 };
  76 
  77 class SymbolTable : public RehashableHashtable<Symbol*, mtSymbol> {
  78   friend class VMStructs;
  79   friend class ClassFileParser;
  80 
  81 private:
  82   // The symbol table
  83   static SymbolTable* _the_table;
  84 
  85   // Set if one bucket is out of balance due to hash algorithm deficiency
  86   static bool _needs_rehashing;
  87 
  88   // For statistics
  89   static int _symbols_removed;
  90   static int _symbols_counted;
  91 
  92   Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F
  93 
  94   // Adding elements
  95   Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue,
  96                     bool c_heap, TRAPS);
  97   bool basic_add(ClassLoaderData* loader_data,
  98                  constantPoolHandle cp, int names_count,
  99                  const char** names, int* lengths, int* cp_indices,
 100                  unsigned int* hashValues, TRAPS);
 101 
 102   static void new_symbols(ClassLoaderData* loader_data,
 103                           constantPoolHandle cp, int names_count,
 104                           const char** name, int* lengths,
 105                           int* cp_indices, unsigned int* hashValues,
 106                           TRAPS) {
 107     add(loader_data, cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
 108   }
 109 
 110   Symbol* lookup(int index, const char* name, int len, unsigned int hash);
 111 
 112   SymbolTable()
 113     : RehashableHashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>)) {}
 114 
 115   SymbolTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
 116     : RehashableHashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>), t,
 117                 number_of_entries) {}
 118 
 119   // Arena for permanent symbols (null class loader) that are never unloaded
 120   static Arena*  _arena;
 121   static Arena* arena() { return _arena; }  // called for statistics
 122 
 123   static void initialize_symbols(int arena_alloc_size = 0);
 124 
 125   static volatile int _parallel_claimed_idx;
 126 
 127   // Release any dead symbols
 128   static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total);
 129 public:
 130   enum {
 131     symbol_alloc_batch_size = 8,
 132     // Pick initial size based on java -version size measurements
 133     symbol_alloc_arena_size = 360*K
 134   };
 135 
 136   // The symbol table


 235 
 236   // Sharing
 237   static void copy_buckets(char** top, char*end) {
 238     the_table()->Hashtable<Symbol*, mtSymbol>::copy_buckets(top, end);
 239   }
 240   static void copy_table(char** top, char*end) {
 241     the_table()->Hashtable<Symbol*, mtSymbol>::copy_table(top, end);
 242   }
 243   static void reverse(void* boundary = NULL) {
 244     the_table()->Hashtable<Symbol*, mtSymbol>::reverse(boundary);
 245   }
 246 
 247   // Rehash the symbol table if it gets out of balance
 248   static void rehash_table();
 249   static bool needs_rehashing()         { return _needs_rehashing; }
 250   // Parallel chunked scanning
 251   static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
 252   static int parallel_claimed_index()        { return _parallel_claimed_idx; }
 253 };
 254 
 255 class StringTable : public RehashableHashtable<oop, mtSymbol> {
 256   friend class VMStructs;
 257 
 258 private:
 259   // The string table
 260   static StringTable* _the_table;
 261 
 262   // Set if one bucket is out of balance due to hash algorithm deficiency
 263   static bool _needs_rehashing;
 264 
 265   // Claimed high water mark for parallel chunked scanning
 266   static volatile int _parallel_claimed_idx;
 267 
 268   static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
 269   oop basic_add(int index, Handle string_or_null, jchar* name, int len,
 270                 unsigned int hashValue, TRAPS);
 271 
 272   oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
 273 
 274   // Apply the give oop closure to the entries to the buckets
 275   // in the range [start_idx, end_idx).
 276   static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx);
 277   // Unlink or apply the give oop closure to the entries to the buckets
 278   // in the range [start_idx, end_idx).
 279   static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
 280 
 281   StringTable() : RehashableHashtable<oop, mtSymbol>((int)StringTableSize,
 282                               sizeof (HashtableEntry<oop, mtSymbol>)) {}
 283 
 284   StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
 285     : RehashableHashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t,
 286                      number_of_entries) {}
 287 public:
 288   // The string table
 289   static StringTable* the_table() { return _the_table; }
 290 
 291   // Size of one bucket in the string table.  Used when checking for rollover.
 292   static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); }
 293 
 294   static void create_table() {
 295     assert(_the_table == NULL, "One string table allowed.");
 296     _the_table = new StringTable();
 297   }
 298 
 299   // GC support
 300   //   Delete pointers to otherwise-unreachable objects.
 301   static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) {
 302     int processed = 0;
 303     int removed = 0;
 304     unlink_or_oops_do(cl, f, &processed, &removed);
 305   }