38 // |
38 // |
39 // %note: |
39 // %note: |
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 class outputStream; |
43 |
44 |
44 |
45 |
45 // Class to hold a newly created or referenced Symbol* temporarily in scope. |
46 // 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 // 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 // symbol table and add to the symbol's reference count. |
76 |
77 |
77 private: |
78 private: |
78 // The symbol table |
79 // The symbol table |
79 static SymbolTable* _the_table; |
80 static SymbolTable* _the_table; |
80 |
81 |
|
82 // Set if one bucket is out of balance due to hash algorithm deficiency |
|
83 static bool _needs_rehashing; |
|
84 static jint _seed; |
|
85 |
81 // For statistics |
86 // For statistics |
82 static int symbols_removed; |
87 static int symbols_removed; |
83 static int symbols_counted; |
88 static int symbols_counted; |
84 |
89 |
85 Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F |
90 Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F |
117 // Arena for permanent symbols (null class loader) that are never unloaded |
122 // Arena for permanent symbols (null class loader) that are never unloaded |
118 static Arena* _arena; |
123 static Arena* _arena; |
119 static Arena* arena() { return _arena; } // called for statistics |
124 static Arena* arena() { return _arena; } // called for statistics |
120 |
125 |
121 static void initialize_symbols(int arena_alloc_size = 0); |
126 static void initialize_symbols(int arena_alloc_size = 0); |
|
127 |
|
128 static bool use_alternate_hashcode() { return _seed != 0; } |
|
129 static jint seed() { return _seed; } |
|
130 |
|
131 unsigned int new_hash(Symbol* sym); |
122 public: |
132 public: |
123 enum { |
133 enum { |
124 symbol_alloc_batch_size = 8, |
134 symbol_alloc_batch_size = 8, |
125 // Pick initial size based on java -version size measurements |
135 // Pick initial size based on java -version size measurements |
126 symbol_alloc_arena_size = 360*K |
136 symbol_alloc_arena_size = 360*K |
144 // if CDS give symbol table a default arena size since most symbols |
154 // if CDS give symbol table a default arena size since most symbols |
145 // are already allocated in the shared misc section. |
155 // are already allocated in the shared misc section. |
146 initialize_symbols(); |
156 initialize_symbols(); |
147 } |
157 } |
148 |
158 |
|
159 static unsigned int hash_symbol(const char* s, int len, unsigned int hashValue = 0); |
|
160 |
149 static Symbol* lookup(const char* name, int len, TRAPS); |
161 static Symbol* lookup(const char* name, int len, TRAPS); |
150 // lookup only, won't add. Also calculate hash. |
162 // lookup only, won't add. Also calculate hash. |
151 static Symbol* lookup_only(const char* name, int len, unsigned int& hash); |
163 static Symbol* lookup_only(const char* name, int len, unsigned int& hash); |
152 // Only copy to C string to be added if lookup failed. |
164 // Only copy to C string to be added if lookup failed. |
153 static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS); |
165 static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS); |
206 static void print_histogram() PRODUCT_RETURN; |
218 static void print_histogram() PRODUCT_RETURN; |
207 static void print() PRODUCT_RETURN; |
219 static void print() PRODUCT_RETURN; |
208 |
220 |
209 // Debugging |
221 // Debugging |
210 static void verify(); |
222 static void verify(); |
|
223 static void dump(outputStream* st); |
211 |
224 |
212 // Sharing |
225 // Sharing |
213 static void copy_buckets(char** top, char*end) { |
226 static void copy_buckets(char** top, char*end) { |
214 the_table()->Hashtable<Symbol*>::copy_buckets(top, end); |
227 the_table()->Hashtable<Symbol*>::copy_buckets(top, end); |
215 } |
228 } |
217 the_table()->Hashtable<Symbol*>::copy_table(top, end); |
230 the_table()->Hashtable<Symbol*>::copy_table(top, end); |
218 } |
231 } |
219 static void reverse(void* boundary = NULL) { |
232 static void reverse(void* boundary = NULL) { |
220 the_table()->Hashtable<Symbol*>::reverse(boundary); |
233 the_table()->Hashtable<Symbol*>::reverse(boundary); |
221 } |
234 } |
|
235 |
|
236 // Rehash the symbol table if it gets out of balance |
|
237 static void rehash_table(); |
|
238 static bool needs_rehashing() { return _needs_rehashing; } |
222 }; |
239 }; |
|
240 |
223 |
241 |
224 class StringTable : public Hashtable<oop> { |
242 class StringTable : public Hashtable<oop> { |
225 friend class VMStructs; |
243 friend class VMStructs; |
226 |
244 |
227 private: |
245 private: |
228 // The string table |
246 // The string table |
229 static StringTable* _the_table; |
247 static StringTable* _the_table; |
230 |
248 |
|
249 // Set if one bucket is out of balance due to hash algorithm deficiency |
|
250 static bool _needs_rehashing; |
|
251 static jint _seed; |
|
252 |
231 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); |
253 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); |
232 oop basic_add(int index, Handle string_or_null, jchar* name, int len, |
254 oop basic_add(int index, Handle string_or_null, jchar* name, int len, |
233 unsigned int hashValue, TRAPS); |
255 unsigned int hashValue, TRAPS); |
234 |
256 |
235 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); |
257 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); |
239 |
261 |
240 StringTable(HashtableBucket* t, int number_of_entries) |
262 StringTable(HashtableBucket* t, int number_of_entries) |
241 : Hashtable<oop>((int)StringTableSize, sizeof (HashtableEntry<oop>), t, |
263 : Hashtable<oop>((int)StringTableSize, sizeof (HashtableEntry<oop>), t, |
242 number_of_entries) {} |
264 number_of_entries) {} |
243 |
265 |
|
266 static bool use_alternate_hashcode() { return _seed != 0; } |
|
267 static jint seed() { return _seed; } |
|
268 |
|
269 unsigned int new_hash(oop s); |
244 public: |
270 public: |
245 // The string table |
271 // The string table |
246 static StringTable* the_table() { return _the_table; } |
272 static StringTable* the_table() { return _the_table; } |
247 |
273 |
248 static void create_table() { |
274 static void create_table() { |
263 static void unlink(BoolObjectClosure* cl); |
289 static void unlink(BoolObjectClosure* cl); |
264 |
290 |
265 // Invoke "f->do_oop" on the locations of all oops in the table. |
291 // Invoke "f->do_oop" on the locations of all oops in the table. |
266 static void oops_do(OopClosure* f); |
292 static void oops_do(OopClosure* f); |
267 |
293 |
|
294 // Hashing algorithm, used as the hash value used by the |
|
295 // StringTable for bucket selection and comparison (stored in the |
|
296 // HashtableEntry structures). This is used in the String.intern() method. |
|
297 static unsigned int hash_string(const jchar* s, int len, unsigned int hashValue = 0); |
|
298 |
|
299 // Internal test. |
|
300 static void test_alt_hash() PRODUCT_RETURN; |
|
301 |
268 // Probing |
302 // Probing |
269 static oop lookup(Symbol* symbol); |
303 static oop lookup(Symbol* symbol); |
270 |
304 |
271 // Interning |
305 // Interning |
272 static oop intern(Symbol* symbol, TRAPS); |
306 static oop intern(Symbol* symbol, TRAPS); |
273 static oop intern(oop string, TRAPS); |
307 static oop intern(oop string, TRAPS); |
274 static oop intern(const char *utf8_string, TRAPS); |
308 static oop intern(const char *utf8_string, TRAPS); |
275 |
309 |
276 // Debugging |
310 // Debugging |
277 static void verify(); |
311 static void verify(); |
|
312 static void dump(outputStream* st); |
278 |
313 |
279 // Sharing |
314 // Sharing |
280 static void copy_buckets(char** top, char*end) { |
315 static void copy_buckets(char** top, char*end) { |
281 the_table()->Hashtable<oop>::copy_buckets(top, end); |
316 the_table()->Hashtable<oop>::copy_buckets(top, end); |
282 } |
317 } |
284 the_table()->Hashtable<oop>::copy_table(top, end); |
319 the_table()->Hashtable<oop>::copy_table(top, end); |
285 } |
320 } |
286 static void reverse() { |
321 static void reverse() { |
287 the_table()->Hashtable<oop>::reverse(); |
322 the_table()->Hashtable<oop>::reverse(); |
288 } |
323 } |
|
324 |
|
325 // Rehash the symbol table if it gets out of balance |
|
326 static void rehash_table(); |
|
327 static bool needs_rehashing() { return _needs_rehashing; } |
289 }; |
328 }; |
290 |
|
291 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |
329 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |