hotspot/src/share/vm/classfile/symbolTable.hpp
changeset 8076 96d498ec7ae1
parent 7397 5b173b4ca846
child 8727 1642a45f024f
equal deleted inserted replaced
8075:582dd25571b2 8076:96d498ec7ae1
    24 
    24 
    25 #ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
    25 #ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
    26 #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
    26 #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
    27 
    27 
    28 #include "memory/allocation.inline.hpp"
    28 #include "memory/allocation.inline.hpp"
    29 #include "oops/symbolOop.hpp"
    29 #include "oops/symbol.hpp"
    30 #include "utilities/hashtable.hpp"
    30 #include "utilities/hashtable.hpp"
    31 
    31 
    32 // The symbol table holds all symbolOops and corresponding interned strings.
    32 // The symbol table holds all Symbol*s and corresponding interned strings.
    33 // symbolOops and literal strings should be canonicalized.
    33 // Symbol*s and literal strings should be canonicalized.
    34 //
    34 //
    35 // The interned strings are created lazily.
    35 // The interned strings are created lazily.
    36 //
    36 //
    37 // It is implemented as an open hash table with a fixed number of buckets.
    37 // It is implemented as an open hash table with a fixed number of buckets.
    38 //
    38 //
    40 //  - symbolTableEntrys are allocated in blocks to reduce the space overhead.
    40 //  - symbolTableEntrys are allocated in blocks to reduce the space overhead.
    41 
    41 
    42 class BoolObjectClosure;
    42 class BoolObjectClosure;
    43 
    43 
    44 
    44 
    45 class SymbolTable : public Hashtable {
    45 // Class to hold a newly created or referenced Symbol* temporarily in scope.
       
    46 // new_symbol() and lookup() will create a Symbol* if not already in the
       
    47 // symbol table and add to the symbol's reference count.
       
    48 // probe() and lookup_only() will increment the refcount if symbol is found.
       
    49 class TempNewSymbol : public StackObj {
       
    50   Symbol* _temp;
       
    51 
       
    52  public:
       
    53   TempNewSymbol() : _temp(NULL) {}
       
    54   // Creating or looking up a symbol increments the symbol's reference count
       
    55   TempNewSymbol(Symbol *s) : _temp(s) {}
       
    56 
       
    57   // Operator= increments reference count.
       
    58   void operator=(const TempNewSymbol &s) {
       
    59     _temp = s._temp;
       
    60     if (_temp !=NULL) _temp->increment_refcount();
       
    61   }
       
    62 
       
    63   // Decrement reference counter so it can go away if it's unique
       
    64   ~TempNewSymbol() { if (_temp != NULL) _temp->decrement_refcount(); }
       
    65 
       
    66   // Operators so they can be used like Symbols
       
    67   Symbol* operator -> () const                   { return _temp; }
       
    68   bool    operator == (Symbol* o) const          { return _temp == o; }
       
    69   // Sneaky conversion function
       
    70   operator Symbol*()                             { return _temp; }
       
    71 };
       
    72 
       
    73 class SymbolTable : public Hashtable<Symbol*> {
    46   friend class VMStructs;
    74   friend class VMStructs;
       
    75   friend class ClassFileParser;
    47 
    76 
    48 private:
    77 private:
    49   // The symbol table
    78   // The symbol table
    50   static SymbolTable* _the_table;
    79   static SymbolTable* _the_table;
    51 
    80 
       
    81   // For statistics
       
    82   static int symbols_removed;
       
    83   static int symbols_counted;
       
    84 
       
    85   Symbol* allocate_symbol(const u1* name, int len, TRAPS);   // Assumes no characters larger than 0x7F
       
    86   bool allocate_symbols(int names_count, const u1** names, int* lengths, Symbol** syms, TRAPS);
       
    87 
    52   // Adding elements
    88   // Adding elements
    53   symbolOop basic_add(int index, u1* name, int len,
    89   Symbol* basic_add(int index, u1* name, int len,
    54                       unsigned int hashValue, TRAPS);
    90                       unsigned int hashValue, TRAPS);
    55   bool basic_add(constantPoolHandle cp, int names_count,
    91   bool basic_add(constantPoolHandle cp, int names_count,
    56                  const char** names, int* lengths, int* cp_indices,
    92                  const char** names, int* lengths, int* cp_indices,
    57                  unsigned int* hashValues, TRAPS);
    93                  unsigned int* hashValues, TRAPS);
    58 
    94 
       
    95   static void new_symbols(constantPoolHandle cp, int names_count,
       
    96                           const char** name, int* lengths,
       
    97                           int* cp_indices, unsigned int* hashValues,
       
    98                           TRAPS) {
       
    99     add(cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
       
   100   }
       
   101 
       
   102 
    59   // Table size
   103   // Table size
    60   enum {
   104   enum {
    61     symbol_table_size = 20011
   105     symbol_table_size = 20011
    62   };
   106   };
    63 
   107 
    64   symbolOop lookup(int index, const char* name, int len, unsigned int hash);
   108   Symbol* lookup(int index, const char* name, int len, unsigned int hash);
    65 
   109 
    66   SymbolTable()
   110   SymbolTable()
    67     : Hashtable(symbol_table_size, sizeof (HashtableEntry)) {}
   111     : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>)) {}
    68 
   112 
    69   SymbolTable(HashtableBucket* t, int number_of_entries)
   113   SymbolTable(HashtableBucket* t, int number_of_entries)
    70     : Hashtable(symbol_table_size, sizeof (HashtableEntry), t,
   114     : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>), t,
    71                 number_of_entries) {}
   115                 number_of_entries) {}
    72 
   116 
    73 
   117 
    74 public:
   118 public:
    75   enum {
   119   enum {
    90     assert(length == symbol_table_size * sizeof(HashtableBucket),
   134     assert(length == symbol_table_size * sizeof(HashtableBucket),
    91            "bad shared symbol size.");
   135            "bad shared symbol size.");
    92     _the_table = new SymbolTable(t, number_of_entries);
   136     _the_table = new SymbolTable(t, number_of_entries);
    93   }
   137   }
    94 
   138 
    95   static symbolOop lookup(const char* name, int len, TRAPS);
   139   static Symbol* lookup(const char* name, int len, TRAPS);
    96   // lookup only, won't add. Also calculate hash.
   140   // lookup only, won't add. Also calculate hash.
    97   static symbolOop lookup_only(const char* name, int len, unsigned int& hash);
   141   static Symbol* lookup_only(const char* name, int len, unsigned int& hash);
    98   // Only copy to C string to be added if lookup failed.
   142   // Only copy to C string to be added if lookup failed.
    99   static symbolOop lookup(symbolHandle sym, int begin, int end, TRAPS);
   143   static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS);
       
   144 
       
   145   static void release(Symbol* sym);
   100 
   146 
   101   // jchar (utf16) version of lookups
   147   // jchar (utf16) version of lookups
   102   static symbolOop lookup_unicode(const jchar* name, int len, TRAPS);
   148   static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
   103   static symbolOop lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
   149   static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
   104 
   150 
   105   static void add(constantPoolHandle cp, int names_count,
   151   static void add(constantPoolHandle cp, int names_count,
   106                   const char** names, int* lengths, int* cp_indices,
   152                   const char** names, int* lengths, int* cp_indices,
   107                   unsigned int* hashValues, TRAPS);
   153                   unsigned int* hashValues, TRAPS);
   108 
   154 
   109   // GC support
   155   // Release any dead symbols
   110   //   Delete pointers to otherwise-unreachable objects.
   156   static void unlink();
   111   static void unlink(BoolObjectClosure* cl) {
   157 
   112     the_table()->Hashtable::unlink(cl);
   158   // iterate over symbols
   113   }
   159   static void symbols_do(SymbolClosure *cl);
   114 
   160 
   115   // Invoke "f->do_oop" on the locations of all oops in the table.
   161   // Symbol creation
   116   static void oops_do(OopClosure* f) {
   162   static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) {
   117     the_table()->Hashtable::oops_do(f);
   163     assert(utf8_buffer != NULL, "just checking");
       
   164     return lookup(utf8_buffer, length, THREAD);
       
   165   }
       
   166   static Symbol*       new_symbol(const char* name, TRAPS) {
       
   167     return new_symbol(name, (int)strlen(name), THREAD);
       
   168   }
       
   169   static Symbol*       new_symbol(const Symbol* sym, int begin, int end, TRAPS) {
       
   170     assert(begin <= end && end <= sym->utf8_length(), "just checking");
       
   171     return lookup(sym, begin, end, THREAD);
   118   }
   172   }
   119 
   173 
   120   // Symbol lookup
   174   // Symbol lookup
   121   static symbolOop lookup(int index, const char* name, int len, TRAPS);
   175   static Symbol* lookup(int index, const char* name, int len, TRAPS);
   122 
   176 
   123   // Needed for preloading classes in signatures when compiling.
   177   // Needed for preloading classes in signatures when compiling.
   124   // Returns the symbol is already present in symbol table, otherwise
   178   // Returns the symbol is already present in symbol table, otherwise
   125   // NULL.  NO ALLOCATION IS GUARANTEED!
   179   // NULL.  NO ALLOCATION IS GUARANTEED!
   126   static symbolOop probe(const char* name, int len) {
   180   static Symbol* probe(const char* name, int len) {
   127     unsigned int ignore_hash;
   181     unsigned int ignore_hash;
   128     return lookup_only(name, len, ignore_hash);
   182     return lookup_only(name, len, ignore_hash);
   129   }
   183   }
   130   static symbolOop probe_unicode(const jchar* name, int len) {
   184   static Symbol* probe_unicode(const jchar* name, int len) {
   131     unsigned int ignore_hash;
   185     unsigned int ignore_hash;
   132     return lookup_only_unicode(name, len, ignore_hash);
   186     return lookup_only_unicode(name, len, ignore_hash);
   133   }
   187   }
   134 
   188 
   135   // Histogram
   189   // Histogram
   136   static void print_histogram()     PRODUCT_RETURN;
   190   static void print_histogram()     PRODUCT_RETURN;
       
   191   static void print()     PRODUCT_RETURN;
   137 
   192 
   138   // Debugging
   193   // Debugging
   139   static void verify();
   194   static void verify();
   140 
   195 
   141   // Sharing
   196   // Sharing
   142   static void copy_buckets(char** top, char*end) {
   197   static void copy_buckets(char** top, char*end) {
   143     the_table()->Hashtable::copy_buckets(top, end);
   198     the_table()->Hashtable<Symbol*>::copy_buckets(top, end);
   144   }
   199   }
   145   static void copy_table(char** top, char*end) {
   200   static void copy_table(char** top, char*end) {
   146     the_table()->Hashtable::copy_table(top, end);
   201     the_table()->Hashtable<Symbol*>::copy_table(top, end);
   147   }
   202   }
   148   static void reverse(void* boundary = NULL) {
   203   static void reverse(void* boundary = NULL) {
   149     ((Hashtable*)the_table())->reverse(boundary);
   204     the_table()->Hashtable<Symbol*>::reverse(boundary);
   150   }
   205   }
   151 };
   206 };
   152 
   207 
   153 
   208 class StringTable : public Hashtable<oop> {
   154 class StringTable : public Hashtable {
       
   155   friend class VMStructs;
   209   friend class VMStructs;
   156 
   210 
   157 private:
   211 private:
   158   // The string table
   212   // The string table
   159   static StringTable* _the_table;
   213   static StringTable* _the_table;
   167     string_table_size = 1009
   221     string_table_size = 1009
   168   };
   222   };
   169 
   223 
   170   oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
   224   oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
   171 
   225 
   172   StringTable() : Hashtable(string_table_size, sizeof (HashtableEntry)) {}
   226   StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {}
   173 
   227 
   174   StringTable(HashtableBucket* t, int number_of_entries)
   228   StringTable(HashtableBucket* t, int number_of_entries)
   175     : Hashtable(string_table_size, sizeof (HashtableEntry), t,
   229     : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t,
   176                 number_of_entries) {}
   230                 number_of_entries) {}
   177 
   231 
   178 public:
   232 public:
   179   // The string table
   233   // The string table
   180   static StringTable* the_table() { return _the_table; }
   234   static StringTable* the_table() { return _the_table; }
   190     assert(length == string_table_size * sizeof(HashtableBucket),
   244     assert(length == string_table_size * sizeof(HashtableBucket),
   191            "bad shared string size.");
   245            "bad shared string size.");
   192     _the_table = new StringTable(t, number_of_entries);
   246     _the_table = new StringTable(t, number_of_entries);
   193   }
   247   }
   194 
   248 
   195 
       
   196   static int hash_string(jchar* s, int len);
   249   static int hash_string(jchar* s, int len);
   197 
       
   198 
   250 
   199   // GC support
   251   // GC support
   200   //   Delete pointers to otherwise-unreachable objects.
   252   //   Delete pointers to otherwise-unreachable objects.
   201   static void unlink(BoolObjectClosure* cl) {
   253   static void unlink(BoolObjectClosure* cl);
   202     the_table()->Hashtable::unlink(cl);
       
   203   }
       
   204 
   254 
   205   // Invoke "f->do_oop" on the locations of all oops in the table.
   255   // Invoke "f->do_oop" on the locations of all oops in the table.
   206   static void oops_do(OopClosure* f) {
   256   static void oops_do(OopClosure* f);
   207     the_table()->Hashtable::oops_do(f);
       
   208   }
       
   209 
   257 
   210   // Probing
   258   // Probing
   211   static oop lookup(symbolOop symbol);
   259   static oop lookup(Symbol* symbol);
   212 
   260 
   213   // Interning
   261   // Interning
   214   static oop intern(symbolOop symbol, TRAPS);
   262   static oop intern(Symbol* symbol, TRAPS);
   215   static oop intern(oop string, TRAPS);
   263   static oop intern(oop string, TRAPS);
   216   static oop intern(const char *utf8_string, TRAPS);
   264   static oop intern(const char *utf8_string, TRAPS);
   217 
   265 
   218   // Debugging
   266   // Debugging
   219   static void verify();
   267   static void verify();
   220 
   268 
   221   // Sharing
   269   // Sharing
   222   static void copy_buckets(char** top, char*end) {
   270   static void copy_buckets(char** top, char*end) {
   223     the_table()->Hashtable::copy_buckets(top, end);
   271     the_table()->Hashtable<oop>::copy_buckets(top, end);
   224   }
   272   }
   225   static void copy_table(char** top, char*end) {
   273   static void copy_table(char** top, char*end) {
   226     the_table()->Hashtable::copy_table(top, end);
   274     the_table()->Hashtable<oop>::copy_table(top, end);
   227   }
   275   }
   228   static void reverse() {
   276   static void reverse() {
   229     ((BasicHashtable*)the_table())->reverse();
   277     the_table()->Hashtable<oop>::reverse();
   230   }
   278   }
   231 };
   279 };
   232 
   280 
   233 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
   281 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP