diff -r 1527aaaeb42d -r 45644c5f6b8e hotspot/src/share/vm/classfile/symbolTable.cpp --- a/hotspot/src/share/vm/classfile/symbolTable.cpp Thu May 11 14:13:59 2017 -0700 +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Mon May 15 12:20:15 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,7 +98,7 @@ int SymbolTable::_symbols_counted = 0; volatile int SymbolTable::_parallel_claimed_idx = 0; -void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int* removed) { +void SymbolTable::buckets_unlink(int start_idx, int end_idx, BucketUnlinkContext* context) { for (int i = start_idx; i < end_idx; ++i) { HashtableEntry** p = the_table()->bucket_addr(i); HashtableEntry* entry = the_table()->bucket(i); @@ -111,15 +111,14 @@ break; } Symbol* s = entry->literal(); - (*processed)++; + context->_num_processed++; assert(s != NULL, "just checking"); // If reference count is zero, remove. if (s->refcount() == 0) { assert(!entry->is_shared(), "shared entries should be kept live"); delete s; - (*removed)++; *p = entry->next(); - the_table()->free_entry(entry); + context->free_entry(entry); } else { p = entry->next_addr(); } @@ -132,17 +131,20 @@ // Remove unreferenced symbols from the symbol table // This is done late during GC. void SymbolTable::unlink(int* processed, int* removed) { - size_t memory_total = 0; - buckets_unlink(0, the_table()->table_size(), processed, removed); - _symbols_removed += *removed; - _symbols_counted += *processed; + BucketUnlinkContext context; + buckets_unlink(0, the_table()->table_size(), &context); + _the_table->bulk_free_entries(&context); + *processed = context._num_processed; + *removed = context._num_removed; + + _symbols_removed = context._num_removed; + _symbols_counted = context._num_processed; } void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) { const int limit = the_table()->table_size(); - size_t memory_total = 0; - + BucketUnlinkContext context; for (;;) { // Grab next set of buckets to scan int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; @@ -152,10 +154,15 @@ } int end_idx = MIN2(limit, start_idx + ClaimChunkSize); - buckets_unlink(start_idx, end_idx, processed, removed); + buckets_unlink(start_idx, end_idx, &context); } - Atomic::add(*processed, &_symbols_counted); - Atomic::add(*removed, &_symbols_removed); + + _the_table->bulk_free_entries(&context); + *processed = context._num_processed; + *removed = context._num_removed; + + Atomic::add(context._num_processed, &_symbols_counted); + Atomic::add(context._num_removed, &_symbols_removed); } // Create a new table and using alternate hash code, populate the new table