symbolTable.hpp revision 2062:3582bf76420e
110723Sbae/* 213655Savstepan * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 310723Sbae * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 410723Sbae * 510723Sbae * This code is free software; you can redistribute it and/or modify it 610723Sbae * under the terms of the GNU General Public License version 2 only, as 710723Sbae * published by the Free Software Foundation. 810723Sbae * 910723Sbae * This code is distributed in the hope that it will be useful, but WITHOUT 1010723Sbae * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1110723Sbae * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1210723Sbae * version 2 for more details (a copy is included in the LICENSE file that 1310723Sbae * accompanied this code). 1410723Sbae * 1510723Sbae * You should have received a copy of the GNU General Public License version 1610723Sbae * 2 along with this work; if not, write to the Free Software Foundation, 1710723Sbae * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1810723Sbae * 1910723Sbae * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2010723Sbae * or visit www.oracle.com if you need additional information or have any 2110723Sbae * questions. 2210723Sbae * 2310723Sbae */ 2410723Sbae 2510723Sbae#ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP 2610723Sbae#define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP 2710723Sbae 2810723Sbae#include "memory/allocation.inline.hpp" 2910723Sbae#include "oops/symbol.hpp" 3010723Sbae#include "utilities/hashtable.hpp" 3110723Sbae 3210723Sbae// The symbol table holds all Symbol*s and corresponding interned strings. 3310723Sbae// Symbol*s and literal strings should be canonicalized. 3410723Sbae// 3510723Sbae// The interned strings are created lazily. 3610723Sbae// 3710723Sbae// It is implemented as an open hash table with a fixed number of buckets. 3810723Sbae// 3910723Sbae// %note: 4010723Sbae// - symbolTableEntrys are allocated in blocks to reduce the space overhead. 4110723Sbae 4210723Sbaeclass BoolObjectClosure; 4310723Sbae 4410723Sbae 4510723Sbae// Class to hold a newly created or referenced Symbol* temporarily in scope. 4610723Sbae// new_symbol() and lookup() will create a Symbol* if not already in the 4710723Sbae// symbol table and add to the symbol's reference count. 4810723Sbae// probe() and lookup_only() will increment the refcount if symbol is found. 4910723Sbaeclass TempNewSymbol : public StackObj { 5010723Sbae Symbol* _temp; 5110723Sbae 5210723Sbae public: 5310723Sbae TempNewSymbol() : _temp(NULL) {} 5410723Sbae // Creating or looking up a symbol increments the symbol's reference count 5513655Savstepan TempNewSymbol(Symbol *s) : _temp(s) {} 5610723Sbae 5710723Sbae // Operator= increments reference count. 5810723Sbae void operator=(const TempNewSymbol &s) { 5910723Sbae _temp = s._temp; 6010723Sbae if (_temp !=NULL) _temp->increment_refcount(); 6110723Sbae } 6210723Sbae 6310723Sbae // Decrement reference counter so it can go away if it's unique 6410723Sbae ~TempNewSymbol() { if (_temp != NULL) _temp->decrement_refcount(); } 6510723Sbae 6610723Sbae // Operators so they can be used like Symbols 6710723Sbae Symbol* operator -> () const { return _temp; } 6810723Sbae bool operator == (Symbol* o) const { return _temp == o; } 6910723Sbae // Sneaky conversion function 7010723Sbae operator Symbol*() { return _temp; } 7110723Sbae}; 7210723Sbae 7310723Sbaeclass SymbolTable : public Hashtable<Symbol*> { 7410723Sbae friend class VMStructs; 7510723Sbae friend class ClassFileParser; 7610723Sbae 7710723Sbaeprivate: 7810723Sbae // The symbol table 7910723Sbae static SymbolTable* _the_table; 8010723Sbae 8110723Sbae // For statistics 8210723Sbae static int symbols_removed; 8310723Sbae static int symbols_counted; 8410723Sbae 8510723Sbae Symbol* allocate_symbol(const u1* name, int len, TRAPS); // Assumes no characters larger than 0x7F 8610723Sbae bool allocate_symbols(int names_count, const u1** names, int* lengths, Symbol** syms, TRAPS); 8710723Sbae 8810723Sbae // Adding elements 8910723Sbae Symbol* basic_add(int index, u1* name, int len, 9010723Sbae unsigned int hashValue, TRAPS); 9110723Sbae bool basic_add(constantPoolHandle cp, int names_count, 9210723Sbae const char** names, int* lengths, int* cp_indices, 9310723Sbae unsigned int* hashValues, TRAPS); 9410723Sbae 9510723Sbae static void new_symbols(constantPoolHandle cp, int names_count, 9610723Sbae const char** name, int* lengths, 9710723Sbae int* cp_indices, unsigned int* hashValues, 9810723Sbae TRAPS) { 9910723Sbae add(cp, names_count, name, lengths, cp_indices, hashValues, THREAD); 10010723Sbae } 10110723Sbae 10210723Sbae 10310723Sbae // Table size 10410723Sbae enum { 10510723Sbae symbol_table_size = 20011 10610723Sbae }; 10710723Sbae 10810723Sbae Symbol* lookup(int index, const char* name, int len, unsigned int hash); 10910723Sbae 11010723Sbae SymbolTable() 11110723Sbae : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>)) {} 11210723Sbae 11310723Sbae SymbolTable(HashtableBucket* t, int number_of_entries) 11410723Sbae : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>), t, 11510723Sbae number_of_entries) {} 11610723Sbae 11710723Sbae 11810723Sbaepublic: 11910723Sbae enum { 12010723Sbae symbol_alloc_batch_size = 8 12110723Sbae }; 12210723Sbae 12310723Sbae // The symbol table 12410723Sbae static SymbolTable* the_table() { return _the_table; } 12510723Sbae 12610723Sbae static void create_table() { 12710723Sbae assert(_the_table == NULL, "One symbol table allowed."); 12810723Sbae _the_table = new SymbolTable(); 12910723Sbae } 130 131 static void create_table(HashtableBucket* t, int length, 132 int number_of_entries) { 133 assert(_the_table == NULL, "One symbol table allowed."); 134 assert(length == symbol_table_size * sizeof(HashtableBucket), 135 "bad shared symbol size."); 136 _the_table = new SymbolTable(t, number_of_entries); 137 } 138 139 static Symbol* lookup(const char* name, int len, TRAPS); 140 // lookup only, won't add. Also calculate hash. 141 static Symbol* lookup_only(const char* name, int len, unsigned int& hash); 142 // Only copy to C string to be added if lookup failed. 143 static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS); 144 145 static void release(Symbol* sym); 146 147 // jchar (utf16) version of lookups 148 static Symbol* lookup_unicode(const jchar* name, int len, TRAPS); 149 static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash); 150 151 static void add(constantPoolHandle cp, int names_count, 152 const char** names, int* lengths, int* cp_indices, 153 unsigned int* hashValues, TRAPS); 154 155 // Release any dead symbols 156 static void unlink(); 157 158 // iterate over symbols 159 static void symbols_do(SymbolClosure *cl); 160 161 // Symbol creation 162 static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) { 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); 172 } 173 174 // Symbol lookup 175 static Symbol* lookup(int index, const char* name, int len, TRAPS); 176 177 // Needed for preloading classes in signatures when compiling. 178 // Returns the symbol is already present in symbol table, otherwise 179 // NULL. NO ALLOCATION IS GUARANTEED! 180 static Symbol* probe(const char* name, int len) { 181 unsigned int ignore_hash; 182 return lookup_only(name, len, ignore_hash); 183 } 184 static Symbol* probe_unicode(const jchar* name, int len) { 185 unsigned int ignore_hash; 186 return lookup_only_unicode(name, len, ignore_hash); 187 } 188 189 // Histogram 190 static void print_histogram() PRODUCT_RETURN; 191 static void print() PRODUCT_RETURN; 192 193 // Debugging 194 static void verify(); 195 196 // Sharing 197 static void copy_buckets(char** top, char*end) { 198 the_table()->Hashtable<Symbol*>::copy_buckets(top, end); 199 } 200 static void copy_table(char** top, char*end) { 201 the_table()->Hashtable<Symbol*>::copy_table(top, end); 202 } 203 static void reverse(void* boundary = NULL) { 204 the_table()->Hashtable<Symbol*>::reverse(boundary); 205 } 206}; 207 208class StringTable : public Hashtable<oop> { 209 friend class VMStructs; 210 211private: 212 // The string table 213 static StringTable* _the_table; 214 215 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); 216 oop basic_add(int index, Handle string_or_null, jchar* name, int len, 217 unsigned int hashValue, TRAPS); 218 219 // Table size 220 enum { 221 string_table_size = 1009 222 }; 223 224 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); 225 226 StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {} 227 228 StringTable(HashtableBucket* t, int number_of_entries) 229 : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t, 230 number_of_entries) {} 231 232public: 233 // The string table 234 static StringTable* the_table() { return _the_table; } 235 236 static void create_table() { 237 assert(_the_table == NULL, "One string table allowed."); 238 _the_table = new StringTable(); 239 } 240 241 static void create_table(HashtableBucket* t, int length, 242 int number_of_entries) { 243 assert(_the_table == NULL, "One string table allowed."); 244 assert(length == string_table_size * sizeof(HashtableBucket), 245 "bad shared string size."); 246 _the_table = new StringTable(t, number_of_entries); 247 } 248 249 static int hash_string(jchar* s, int len); 250 251 // GC support 252 // Delete pointers to otherwise-unreachable objects. 253 static void unlink(BoolObjectClosure* cl); 254 255 // Invoke "f->do_oop" on the locations of all oops in the table. 256 static void oops_do(OopClosure* f); 257 258 // Probing 259 static oop lookup(Symbol* symbol); 260 261 // Interning 262 static oop intern(Symbol* symbol, TRAPS); 263 static oop intern(oop string, TRAPS); 264 static oop intern(const char *utf8_string, TRAPS); 265 266 // Debugging 267 static void verify(); 268 269 // Sharing 270 static void copy_buckets(char** top, char*end) { 271 the_table()->Hashtable<oop>::copy_buckets(top, end); 272 } 273 static void copy_table(char** top, char*end) { 274 the_table()->Hashtable<oop>::copy_table(top, end); 275 } 276 static void reverse() { 277 the_table()->Hashtable<oop>::reverse(); 278 } 279}; 280 281#endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP 282