symbolTable.hpp revision 3602:da91efe96a93
1/* 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25#ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP 26#define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP 27 28#include "memory/allocation.inline.hpp" 29#include "oops/symbol.hpp" 30#include "utilities/hashtable.hpp" 31 32// The symbol table holds all Symbol*s and corresponding interned strings. 33// Symbol*s and literal strings should be canonicalized. 34// 35// The interned strings are created lazily. 36// 37// It is implemented as an open hash table with a fixed number of buckets. 38// 39// %note: 40// - symbolTableEntrys are allocated in blocks to reduce the space overhead. 41 42class BoolObjectClosure; 43class outputStream; 44 45 46// Class to hold a newly created or referenced Symbol* temporarily in scope. 47// new_symbol() and lookup() will create a Symbol* if not already in the 48// symbol table and add to the symbol's reference count. 49// probe() and lookup_only() will increment the refcount if symbol is found. 50class TempNewSymbol : public StackObj { 51 Symbol* _temp; 52 53 public: 54 TempNewSymbol() : _temp(NULL) {} 55 // Creating or looking up a symbol increments the symbol's reference count 56 TempNewSymbol(Symbol *s) : _temp(s) {} 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 77class SymbolTable : public Hashtable<Symbol*, mtSymbol> { 78 friend class VMStructs; 79 friend class ClassFileParser; 80 81private: 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 // Table size 111 enum { 112 symbol_table_size = 20011 113 }; 114 115 Symbol* lookup(int index, const char* name, int len, unsigned int hash); 116 117 SymbolTable() 118 : Hashtable<Symbol*, mtSymbol>(symbol_table_size, sizeof (HashtableEntry<Symbol*, mtSymbol>)) {} 119 120 SymbolTable(HashtableBucket<mtSymbol>* t, int number_of_entries) 121 : Hashtable<Symbol*, mtSymbol>(symbol_table_size, sizeof (HashtableEntry<Symbol*, mtSymbol>), t, 122 number_of_entries) {} 123 124 // Arena for permanent symbols (null class loader) that are never unloaded 125 static Arena* _arena; 126 static Arena* arena() { return _arena; } // called for statistics 127 128 static void initialize_symbols(int arena_alloc_size = 0); 129public: 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 137 static SymbolTable* the_table() { return _the_table; } 138 139 static void create_table() { 140 assert(_the_table == NULL, "One symbol table allowed."); 141 _the_table = new SymbolTable(); 142 initialize_symbols(symbol_alloc_arena_size); 143 } 144 145 static void create_table(HashtableBucket<mtSymbol>* t, int length, 146 int number_of_entries) { 147 assert(_the_table == NULL, "One symbol table allowed."); 148 assert(length == symbol_table_size * sizeof(HashtableBucket<mtSymbol>), 149 "bad shared symbol size."); 150 _the_table = new SymbolTable(t, number_of_entries); 151 // if CDS give symbol table a default arena size since most symbols 152 // are already allocated in the shared misc section. 153 initialize_symbols(); 154 } 155 156 static unsigned int hash_symbol(const char* s, int len); 157 158 static Symbol* lookup(const char* name, int len, TRAPS); 159 // lookup only, won't add. Also calculate hash. 160 static Symbol* lookup_only(const char* name, int len, unsigned int& hash); 161 // Only copy to C string to be added if lookup failed. 162 static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS); 163 164 static void release(Symbol* sym); 165 166 // Look up the address of the literal in the SymbolTable for this Symbol* 167 static Symbol** lookup_symbol_addr(Symbol* sym); 168 169 // jchar (utf16) version of lookups 170 static Symbol* lookup_unicode(const jchar* name, int len, TRAPS); 171 static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash); 172 173 static void add(ClassLoaderData* loader_data, 174 constantPoolHandle cp, int names_count, 175 const char** names, int* lengths, int* cp_indices, 176 unsigned int* hashValues, TRAPS); 177 178 // Release any dead symbols 179 static void unlink(); 180 181 // iterate over symbols 182 static void symbols_do(SymbolClosure *cl); 183 184 // Symbol creation 185 static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) { 186 assert(utf8_buffer != NULL, "just checking"); 187 return lookup(utf8_buffer, length, THREAD); 188 } 189 static Symbol* new_symbol(const char* name, TRAPS) { 190 return new_symbol(name, (int)strlen(name), THREAD); 191 } 192 static Symbol* new_symbol(const Symbol* sym, int begin, int end, TRAPS) { 193 assert(begin <= end && end <= sym->utf8_length(), "just checking"); 194 return lookup(sym, begin, end, THREAD); 195 } 196 197 // Create a symbol in the arena for symbols that are not deleted 198 static Symbol* new_permanent_symbol(const char* name, TRAPS); 199 200 // Symbol lookup 201 static Symbol* lookup(int index, const char* name, int len, TRAPS); 202 203 // Needed for preloading classes in signatures when compiling. 204 // Returns the symbol is already present in symbol table, otherwise 205 // NULL. NO ALLOCATION IS GUARANTEED! 206 static Symbol* probe(const char* name, int len) { 207 unsigned int ignore_hash; 208 return lookup_only(name, len, ignore_hash); 209 } 210 static Symbol* probe_unicode(const jchar* name, int len) { 211 unsigned int ignore_hash; 212 return lookup_only_unicode(name, len, ignore_hash); 213 } 214 215 // Histogram 216 static void print_histogram() PRODUCT_RETURN; 217 static void print() PRODUCT_RETURN; 218 219 // Debugging 220 static void verify(); 221 static void dump(outputStream* st); 222 223 // Sharing 224 static void copy_buckets(char** top, char*end) { 225 the_table()->Hashtable<Symbol*, mtSymbol>::copy_buckets(top, end); 226 } 227 static void copy_table(char** top, char*end) { 228 the_table()->Hashtable<Symbol*, mtSymbol>::copy_table(top, end); 229 } 230 static void reverse(void* boundary = NULL) { 231 the_table()->Hashtable<Symbol*, mtSymbol>::reverse(boundary); 232 } 233 234 // Rehash the symbol table if it gets out of balance 235 static void rehash_table(); 236 static bool needs_rehashing() { return _needs_rehashing; } 237}; 238 239class StringTable : public Hashtable<oop, mtSymbol> { 240 friend class VMStructs; 241 242private: 243 // The string table 244 static StringTable* _the_table; 245 246 // Set if one bucket is out of balance due to hash algorithm deficiency 247 static bool _needs_rehashing; 248 249 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); 250 oop basic_add(int index, Handle string_or_null, jchar* name, int len, 251 unsigned int hashValue, TRAPS); 252 253 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); 254 255 StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize, 256 sizeof (HashtableEntry<oop, mtSymbol>)) {} 257 258 StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries) 259 : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t, 260 number_of_entries) {} 261public: 262 // The string table 263 static StringTable* the_table() { return _the_table; } 264 265 static void create_table() { 266 assert(_the_table == NULL, "One string table allowed."); 267 _the_table = new StringTable(); 268 } 269 270 static void create_table(HashtableBucket<mtSymbol>* t, int length, 271 int number_of_entries) { 272 assert(_the_table == NULL, "One string table allowed."); 273 assert((size_t)length == StringTableSize * sizeof(HashtableBucket<mtSymbol>), 274 "bad shared string size."); 275 _the_table = new StringTable(t, number_of_entries); 276 } 277 278 // GC support 279 // Delete pointers to otherwise-unreachable objects. 280 static void unlink(BoolObjectClosure* cl); 281 282 // Invoke "f->do_oop" on the locations of all oops in the table. 283 static void oops_do(OopClosure* f); 284 285 // Hashing algorithm, used as the hash value used by the 286 // StringTable for bucket selection and comparison (stored in the 287 // HashtableEntry structures). This is used in the String.intern() method. 288 static unsigned int hash_string(const jchar* s, int len); 289 290 // Internal test. 291 static void test_alt_hash() PRODUCT_RETURN; 292 293 // Probing 294 static oop lookup(Symbol* symbol); 295 296 // Interning 297 static oop intern(Symbol* symbol, TRAPS); 298 static oop intern(oop string, TRAPS); 299 static oop intern(const char *utf8_string, TRAPS); 300 301 // Debugging 302 static void verify(); 303 static void dump(outputStream* st); 304 305 // Sharing 306 static void copy_buckets(char** top, char*end) { 307 the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end); 308 } 309 static void copy_table(char** top, char*end) { 310 the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end); 311 } 312 static void reverse() { 313 the_table()->Hashtable<oop, mtSymbol>::reverse(); 314 } 315 316 // Rehash the symbol table if it gets out of balance 317 static void rehash_table(); 318 static bool needs_rehashing() { return _needs_rehashing; } 319}; 320#endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP 321