--- 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<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
HashtableEntry<Symbol*, mtSymbol>* 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