312 oop result = intern(string, chars, length, CHECK_NULL); |
312 oop result = intern(string, chars, length, CHECK_NULL); |
313 return result; |
313 return result; |
314 } |
314 } |
315 |
315 |
316 void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { |
316 void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { |
317 buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed); |
317 BucketUnlinkContext context; |
|
318 buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), &context); |
|
319 _the_table->bulk_free_entries(&context); |
|
320 *processed = context._num_processed; |
|
321 *removed = context._num_removed; |
318 } |
322 } |
319 |
323 |
320 void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { |
324 void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { |
321 // Readers of the table are unlocked, so we should only be removing |
325 // Readers of the table are unlocked, so we should only be removing |
322 // entries at a safepoint. |
326 // entries at a safepoint. |
323 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
327 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
324 const int limit = the_table()->table_size(); |
328 const int limit = the_table()->table_size(); |
325 |
329 |
|
330 BucketUnlinkContext context; |
326 for (;;) { |
331 for (;;) { |
327 // Grab next set of buckets to scan |
332 // Grab next set of buckets to scan |
328 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; |
333 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; |
329 if (start_idx >= limit) { |
334 if (start_idx >= limit) { |
330 // End of table |
335 // End of table |
331 break; |
336 break; |
332 } |
337 } |
333 |
338 |
334 int end_idx = MIN2(limit, start_idx + ClaimChunkSize); |
339 int end_idx = MIN2(limit, start_idx + ClaimChunkSize); |
335 buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed); |
340 buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, &context); |
336 } |
341 } |
|
342 _the_table->bulk_free_entries(&context); |
|
343 *processed = context._num_processed; |
|
344 *removed = context._num_removed; |
337 } |
345 } |
338 |
346 |
339 void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) { |
347 void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) { |
340 const int limit = the_table()->table_size(); |
348 const int limit = the_table()->table_size(); |
341 |
349 |
357 entry = entry->next(); |
365 entry = entry->next(); |
358 } |
366 } |
359 } |
367 } |
360 } |
368 } |
361 |
369 |
362 void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) { |
370 void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, BucketUnlinkContext* context) { |
363 const int limit = the_table()->table_size(); |
371 const int limit = the_table()->table_size(); |
364 |
372 |
365 assert(0 <= start_idx && start_idx <= limit, |
373 assert(0 <= start_idx && start_idx <= limit, |
366 "start_idx (%d) is out of bounds", start_idx); |
374 "start_idx (%d) is out of bounds", start_idx); |
367 assert(0 <= end_idx && end_idx <= limit, |
375 assert(0 <= end_idx && end_idx <= limit, |