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
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
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 }
246
247 // Rehash the symbol table if it gets out of balance
248 static void rehash_table();
249 static bool needs_rehashing() { return _needs_rehashing; }
250 // Parallel chunked scanning
251 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
252 static int parallel_claimed_index() { return _parallel_claimed_idx; }
253 };
254
255 class StringTable : public Hashtable<oop, mtSymbol> {
256 friend class VMStructs;
257
258 private:
259 // The string table
260 static StringTable* _the_table;
261
262 // Set if one bucket is out of balance due to hash algorithm deficiency
263 static bool _needs_rehashing;
264
265 // Claimed high water mark for parallel chunked scanning
266 static volatile int _parallel_claimed_idx;
267
268 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
269 oop basic_add(int index, Handle string_or_null, jchar* name, int len,
270 unsigned int hashValue, TRAPS);
271
272 oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
273
274 // Apply the give oop closure to the entries to the buckets
275 // in the range [start_idx, end_idx).
276 static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx);
277 // Unlink or apply the give oop closure to the entries to the buckets
278 // in the range [start_idx, end_idx).
279 static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
280
281 StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize,
282 sizeof (HashtableEntry<oop, mtSymbol>)) {}
283
284 StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
285 : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t,
286 number_of_entries) {}
287 public:
288 // The string table
289 static StringTable* the_table() { return _the_table; }
290
291 // Size of one bucket in the string table. Used when checking for rollover.
292 static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); }
293
294 static void create_table() {
295 assert(_the_table == NULL, "One string table allowed.");
296 _the_table = new StringTable();
297 }
298
299 // GC support
300 // Delete pointers to otherwise-unreachable objects.
301 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) {
302 int processed = 0;
303 int removed = 0;
304 unlink_or_oops_do(cl, f, &processed, &removed);
305 }
306 static void unlink(BoolObjectClosure* cl) {
307 int processed = 0;
308 int removed = 0;
309 unlink_or_oops_do(cl, NULL, &processed, &removed);
310 }
311 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed);
312 static void unlink(BoolObjectClosure* cl, int* processed, int* removed) {
313 unlink_or_oops_do(cl, NULL, processed, removed);
314 }
315 // Serially invoke "f->do_oop" on the locations of all oops in the table.
316 static void oops_do(OopClosure* f);
317
318 // Possibly parallel versions of the above
319 static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed);
320 static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) {
321 possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed);
322 }
323 static void possibly_parallel_oops_do(OopClosure* f);
324
325 // Hashing algorithm, used as the hash value used by the
326 // StringTable for bucket selection and comparison (stored in the
327 // HashtableEntry structures). This is used in the String.intern() method.
328 static unsigned int hash_string(const jchar* s, int len);
329
330 // Internal test.
331 static void test_alt_hash() PRODUCT_RETURN;
332
333 // Probing
334 static oop lookup(Symbol* symbol);
335 static oop lookup(jchar* chars, int length);
336
337 // Interning
338 static oop intern(Symbol* symbol, TRAPS);
339 static oop intern(oop string, TRAPS);
340 static oop intern(const char *utf8_string, TRAPS);
341
342 // Debugging
343 static void verify();
344 static void dump(outputStream* st);
345
346 enum VerifyMesgModes {
347 _verify_quietly = 0,
348 _verify_with_mesgs = 1
349 };
350
351 enum VerifyRetTypes {
352 _verify_pass = 0,
353 _verify_fail_continue = 1,
354 _verify_fail_done = 2
355 };
356
357 static VerifyRetTypes compare_entries(int bkt1, int e_cnt1,
358 HashtableEntry<oop, mtSymbol>* e_ptr1,
359 int bkt2, int e_cnt2,
360 HashtableEntry<oop, mtSymbol>* e_ptr2);
361 static VerifyRetTypes verify_entry(int bkt, int e_cnt,
362 HashtableEntry<oop, mtSymbol>* e_ptr,
363 VerifyMesgModes mesg_mode);
364 static int verify_and_compare_entries();
365
366 // Sharing
367 static void copy_buckets(char** top, char*end) {
368 the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end);
369 }
370 static void copy_table(char** top, char*end) {
371 the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end);
372 }
373 static void reverse() {
374 the_table()->Hashtable<oop, mtSymbol>::reverse();
375 }
376
377 // Rehash the symbol table if it gets out of balance
378 static void rehash_table();
379 static bool needs_rehashing() { return _needs_rehashing; }
380
381 // Parallel chunked scanning
382 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
383 static int parallel_claimed_index() { return _parallel_claimed_idx; }
384 };
385 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
|
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
42 class BoolObjectClosure;
43 class outputStream;
44
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 //clear(); //FIXME
60 _temp = s._temp;
61 if (_temp !=NULL) _temp->increment_refcount();
62 }
63
64 // Decrement reference counter so it can go away if it's unique
234
235 // Sharing
236 static void copy_buckets(char** top, char*end) {
237 the_table()->Hashtable<Symbol*, mtSymbol>::copy_buckets(top, end);
238 }
239 static void copy_table(char** top, char*end) {
240 the_table()->Hashtable<Symbol*, mtSymbol>::copy_table(top, end);
241 }
242 static void reverse(void* boundary = NULL) {
243 the_table()->Hashtable<Symbol*, mtSymbol>::reverse(boundary);
244 }
245
246 // Rehash the symbol table if it gets out of balance
247 static void rehash_table();
248 static bool needs_rehashing() { return _needs_rehashing; }
249 // Parallel chunked scanning
250 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
251 static int parallel_claimed_index() { return _parallel_claimed_idx; }
252 };
253
254 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
|