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 42 class BoolObjectClosure; 43 class 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. 50 class 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 144 _the_table = new SymbolTable(); 145 initialize_symbols(symbol_alloc_arena_size); 146 } 147 148 static void create_table(HashtableBucket<mtSymbol>* t, int length, 149 int number_of_entries) { 150 assert(_the_table == NULL, "One symbol table allowed."); 151 152 // If CDS archive used a different symbol table size, use that size instead 153 // which is better than giving an error. 154 SymbolTableSize = length/bucket_size(); 155 156 _the_table = new SymbolTable(t, number_of_entries); 157 // if CDS give symbol table a default arena size since most symbols 158 // are already allocated in the shared misc section. 159 initialize_symbols(); 160 } 161 162 static unsigned int hash_symbol(const char* s, int len); 163 164 static Symbol* lookup(const char* name, int len, TRAPS); 165 // lookup only, won't add. Also calculate hash. 166 static Symbol* lookup_only(const char* name, int len, unsigned int& hash); 167 // Only copy to C string to be added if lookup failed. 168 static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS); 169 170 static void release(Symbol* sym); 171 172 // Look up the address of the literal in the SymbolTable for this Symbol* 173 static Symbol** lookup_symbol_addr(Symbol* sym); 174 175 // jchar (utf16) version of lookups 176 static Symbol* lookup_unicode(const jchar* name, int len, TRAPS); 177 static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash); 178 179 static void add(ClassLoaderData* loader_data, 180 constantPoolHandle cp, int names_count, 181 const char** names, int* lengths, int* cp_indices, 182 unsigned int* hashValues, TRAPS); 183 184 // Release any dead symbols 185 static void unlink() { 186 int processed = 0; 187 int removed = 0; 188 unlink(&processed, &removed); 189 } 190 static void unlink(int* processed, int* removed); 191 // Release any dead symbols, possibly parallel version 192 static void possibly_parallel_unlink(int* processed, int* removed); 193 194 // iterate over symbols 195 static void symbols_do(SymbolClosure *cl); 196 197 // Symbol creation 198 static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) { 199 assert(utf8_buffer != NULL, "just checking"); 200 return lookup(utf8_buffer, length, THREAD); 201 } 202 static Symbol* new_symbol(const char* name, TRAPS) { 203 return new_symbol(name, (int)strlen(name), THREAD); 204 } 205 static Symbol* new_symbol(const Symbol* sym, int begin, int end, TRAPS) { 206 assert(begin <= end && end <= sym->utf8_length(), "just checking"); 207 return lookup(sym, begin, end, THREAD); 208 } 209 210 // Create a symbol in the arena for symbols that are not deleted 211 static Symbol* new_permanent_symbol(const char* name, TRAPS); 212 213 // Symbol lookup 214 static Symbol* lookup(int index, const char* name, int len, TRAPS); 215 216 // Needed for preloading classes in signatures when compiling. 217 // Returns the symbol is already present in symbol table, otherwise 218 // NULL. NO ALLOCATION IS GUARANTEED! 219 static Symbol* probe(const char* name, int len) { 220 unsigned int ignore_hash; 221 return lookup_only(name, len, ignore_hash); 222 } 223 static Symbol* probe_unicode(const jchar* name, int len) { 224 unsigned int ignore_hash; 225 return lookup_only_unicode(name, len, ignore_hash); 226 } 227 228 // Histogram 229 static void print_histogram() PRODUCT_RETURN; 230 static void print() PRODUCT_RETURN; 231 232 // Debugging 233 static void verify(); 234 static void dump(outputStream* st); 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 } | 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 42 class BoolObjectClosure; 43 class outputStream; 44 45 46 // Class to hold a newly created or referenced Symbol* temporarily in scope. 47 // new_symbol() and lookup_and_add() will create a Symbol* if not already in the 48 // symbol table and add to the symbol's reference count. 49 // lookup_and_ignore_hash() and lookup_and_hash() will increment the refcount if symbol is found. 50 class 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 144 _the_table = new SymbolTable(); 145 initialize_symbols(symbol_alloc_arena_size); 146 } 147 148 static void create_table(HashtableBucket<mtSymbol>* t, int length, 149 int number_of_entries) { 150 assert(_the_table == NULL, "One symbol table allowed."); 151 152 // If CDS archive used a different symbol table size, use that size instead 153 // which is better than giving an error. 154 SymbolTableSize = length/bucket_size(); 155 156 _the_table = new SymbolTable(t, number_of_entries); 157 // if CDS give symbol table a default arena size since most symbols 158 // are already allocated in the shared misc section. 159 initialize_symbols(); 160 } 161 162 static unsigned int hash_symbol(const char* s, int len); 163 164 // lookup only, won't add. Also calculate hash. 165 static Symbol* lookup_and_hash(const char* name, int len, unsigned int& hash); 166 // lookup and add if lookup failed 167 static Symbol* lookup_and_add(const char* name, int len, TRAPS); 168 // Only copy to C string to be added if lookup failed. 169 static Symbol* lookup_and_add(const Symbol* sym, int begin, int end, TRAPS); 170 171 static void release(Symbol* sym); 172 173 // Look up the address of the literal in the SymbolTable for this Symbol* 174 static Symbol** lookup_symbol_addr(Symbol* sym); 175 176 // jchar (utf16) version of lookups 177 static Symbol* lookup_and_add_unicode(const jchar* name, int len, TRAPS); 178 static Symbol* lookup_and_hash_unicode(const jchar* name, int len, unsigned int& hash); 179 180 static void add(ClassLoaderData* loader_data, 181 constantPoolHandle cp, int names_count, 182 const char** names, int* lengths, int* cp_indices, 183 unsigned int* hashValues, TRAPS); 184 185 // Release any dead symbols 186 static void unlink() { 187 int processed = 0; 188 int removed = 0; 189 unlink(&processed, &removed); 190 } 191 static void unlink(int* processed, int* removed); 192 // Release any dead symbols, possibly parallel version 193 static void possibly_parallel_unlink(int* processed, int* removed); 194 195 // iterate over symbols 196 static void symbols_do(SymbolClosure *cl); 197 198 // Symbol creation 199 static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) { 200 assert(utf8_buffer != NULL, "just checking"); 201 return lookup_and_add(utf8_buffer, length, THREAD); 202 } 203 static Symbol* new_symbol(const char* name, TRAPS) { 204 return new_symbol(name, (int)strlen(name), THREAD); 205 } 206 static Symbol* new_symbol(const Symbol* sym, int begin, int end, TRAPS) { 207 assert(begin <= end && end <= sym->utf8_length(), "just checking"); 208 return lookup_and_add(sym, begin, end, THREAD); 209 } 210 211 // Create a symbol in the arena for symbols that are not deleted 212 static Symbol* new_permanent_symbol(const char* name, TRAPS); 213 214 // Symbol lookup 215 static Symbol* lookup(int index, const char* name, int len, TRAPS); 216 217 // Needed for preloading classes in signatures when compiling. 218 // Returns the symbol is already present in symbol table, otherwise 219 // NULL. NO ALLOCATION IS GUARANTEED! 220 static Symbol* lookup_and_ignore_hash(const char* name, int len) { 221 unsigned int ignore_hash; 222 return lookup_and_hash(name, len, ignore_hash); 223 } 224 static Symbol* lookup_and_ignore_hash_unicode(const jchar* name, int len) { 225 unsigned int ignore_hash; 226 return lookup_and_hash_unicode(name, len, ignore_hash); 227 } 228 229 // Histogram 230 static void print_histogram() PRODUCT_RETURN; 231 static void print() PRODUCT_RETURN; 232 233 // Debugging 234 static void verify(); 235 static void dump(outputStream* st); 236 237 // Sharing 238 static void copy_buckets(char** top, char*end) { 239 the_table()->Hashtable<Symbol*, mtSymbol>::copy_buckets(top, end); 240 } 241 static void copy_table(char** top, char*end) { 242 the_table()->Hashtable<Symbol*, mtSymbol>::copy_table(top, end); 243 } 244 static void reverse(void* boundary = NULL) { 245 the_table()->Hashtable<Symbol*, mtSymbol>::reverse(boundary); 246 } |