250 // Parallel chunked scanning |
249 // Parallel chunked scanning |
251 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } |
250 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } |
252 static int parallel_claimed_index() { return _parallel_claimed_idx; } |
251 static int parallel_claimed_index() { return _parallel_claimed_idx; } |
253 }; |
252 }; |
254 |
253 |
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 |
254 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |