< prev index next >
src/hotspot/share/classfile/symbolTable.cpp
Print this page
*** 56,88 ****
#define ON_STACK_BUFFER_LENGTH 128
// --------------------------------------------------------------------------
SymbolTable* SymbolTable::_the_table = NULL;
CompactHashtable<Symbol*, char> SymbolTable::_shared_table;
! bool SymbolTable::_alt_hash = false;
// Static arena for symbols that are not deallocated
Arena* SymbolTable::_arena = NULL;
- bool SymbolTable::_lookup_shared_first = false;
- int SymbolTable::_symbols_removed = 0;
- int SymbolTable::_symbols_counted = 0;
static juint murmur_seed = 0;
static inline void _log_trace_symboltable_helper(Symbol* sym, const char* msg) {
#ifndef PRODUCT
if (log_is_enabled(Trace, symboltable)) {
! char *s;
! {
! ResourceMark rm;
! s = sym->as_quoted_ascii();
! s = os::strdup(s);
! }
! if (s == NULL) {
log_trace(symboltable)("%s [%s]", msg, "NULL");
} else {
! log_trace(symboltable)("%s [%s]", msg, s);
! os::free(s);
}
}
#endif // PRODUCT
}
--- 56,79 ----
#define ON_STACK_BUFFER_LENGTH 128
// --------------------------------------------------------------------------
SymbolTable* SymbolTable::_the_table = NULL;
CompactHashtable<Symbol*, char> SymbolTable::_shared_table;
! volatile bool SymbolTable::_alt_hash = false;
! volatile bool SymbolTable::_lookup_shared_first = false;
// Static arena for symbols that are not deallocated
Arena* SymbolTable::_arena = NULL;
static juint murmur_seed = 0;
static inline void _log_trace_symboltable_helper(Symbol* sym, const char* msg) {
#ifndef PRODUCT
if (log_is_enabled(Trace, symboltable)) {
! if (sym->as_quoted_ascii() == NULL) {
log_trace(symboltable)("%s [%s]", msg, "NULL");
} else {
! log_trace(symboltable)("%s [%s]", msg, sym->as_quoted_ascii());
}
}
#endif // PRODUCT
}
*** 103,113 ****
static uintx get_hash(Symbol* const& value, bool* is_dead) {
*is_dead = (value->refcount() == 0);
if (*is_dead) {
return 0;
} else {
! return hash_symbol((char*)value->bytes(), value->utf8_length(), SymbolTable::_alt_hash);
}
}
// We use default allocation/deallocation but counted
static void* allocate_node(size_t size, Symbol* const& value) {
SymbolTable::item_added();
--- 94,104 ----
static uintx get_hash(Symbol* const& value, bool* is_dead) {
*is_dead = (value->refcount() == 0);
if (*is_dead) {
return 0;
} else {
! return hash_symbol((const char*)value->bytes(), value->utf8_length(), SymbolTable::_alt_hash);
}
}
// We use default allocation/deallocation but counted
static void* allocate_node(size_t size, Symbol* const& value) {
SymbolTable::item_added();
*** 126,145 ****
SymbolTableHash::BaseConfig::free_node(memory, value);
SymbolTable::item_removed();
}
};
! static size_t ceil_pow_2(uintx value) {
size_t ret;
for (ret = 1; ((size_t)1 << ret) < value; ++ret);
return ret;
}
SymbolTable::SymbolTable() : _local_table(NULL), _current_size(0), _has_work(0),
! _needs_rehashing(false), _items(0), _uncleaned_items(0) {
! size_t start_size_log_2 = ceil_pow_2(SymbolTableSize);
_current_size = ((size_t)1) << start_size_log_2;
log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
_current_size, start_size_log_2);
_local_table = new SymbolTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
}
--- 117,137 ----
SymbolTableHash::BaseConfig::free_node(memory, value);
SymbolTable::item_removed();
}
};
! static size_t log2_ceil(uintx value) {
size_t ret;
for (ret = 1; ((size_t)1 << ret) < value; ++ret);
return ret;
}
SymbolTable::SymbolTable() : _local_table(NULL), _current_size(0), _has_work(0),
! _needs_rehashing(false), _items_count(0), _uncleaned_items_count(0),
! _symbols_removed(0), _symbols_counted(0) {
! size_t start_size_log_2 = log2_ceil(SymbolTableSize);
_current_size = ((size_t)1) << start_size_log_2;
log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
_current_size, start_size_log_2);
_local_table = new SymbolTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
}
*** 156,191 ****
} else {
delete sym;
}
}
! size_t SymbolTable::item_added() {
! return Atomic::add(1, &(SymbolTable::the_table()->_items));
}
void SymbolTable::set_item_clean_count(size_t ncl) {
! Atomic::store((int)ncl, &(SymbolTable::the_table()->_uncleaned_items));
! log_trace(symboltable)("Set uncleaned items:" INT32_FORMAT, SymbolTable::the_table()->_uncleaned_items);
}
void SymbolTable::mark_item_clean_count() {
! if (Atomic::cmpxchg(1, &(SymbolTable::the_table()->_uncleaned_items), 0) == 0) { // only mark if unset
! log_trace(symboltable)("Marked uncleaned items:" INT32_FORMAT, SymbolTable::the_table()->_uncleaned_items);
}
}
void SymbolTable::item_removed() {
! Atomic::add(1, &(SymbolTable::the_table()->_symbols_removed));
! Atomic::sub(1, &(SymbolTable::the_table()->_items));
}
double SymbolTable::get_load_factor() {
! return (_items*1.0)/_current_size;
}
double SymbolTable::get_dead_factor() {
! return (_uncleaned_items*1.0)/_current_size;
}
size_t SymbolTable::table_size(Thread* thread) {
return ((size_t)(1)) << _local_table->get_size_log2(thread != NULL ? thread
: Thread::current());
--- 148,183 ----
} else {
delete sym;
}
}
! void SymbolTable::item_added() {
! Atomic::inc(&(SymbolTable::the_table()->_items_count));
}
void SymbolTable::set_item_clean_count(size_t ncl) {
! Atomic::store(ncl, &(SymbolTable::the_table()->_uncleaned_items_count));
! log_trace(symboltable)("Set uncleaned items:" SIZE_FORMAT, SymbolTable::the_table()->_uncleaned_items_count);
}
void SymbolTable::mark_item_clean_count() {
! if (Atomic::cmpxchg((size_t)1, &(SymbolTable::the_table()->_uncleaned_items_count), (size_t)0) == 0) { // only mark if unset
! log_trace(symboltable)("Marked uncleaned items:" SIZE_FORMAT, SymbolTable::the_table()->_uncleaned_items_count);
}
}
void SymbolTable::item_removed() {
! Atomic::inc(&(SymbolTable::the_table()->_symbols_removed));
! Atomic::dec(&(SymbolTable::the_table()->_items_count));
}
double SymbolTable::get_load_factor() {
! return (double)_items_count/_current_size;
}
double SymbolTable::get_dead_factor() {
! return (double)_uncleaned_items_count/_current_size;
}
size_t SymbolTable::table_size(Thread* thread) {
return ((size_t)(1)) << _local_table->get_size_log2(thread != NULL ? thread
: Thread::current());
*** 195,219 ****
MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
SymbolTable::the_table()->_has_work = true;
Service_lock->notify_all();
}
! Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
assert (len <= Symbol::max_length(), "should be checked by caller");
Symbol* sym;
if (DumpSharedSpaces) {
c_heap = false;
}
if (c_heap) {
// refcount starts as 1
! sym = new (len, THREAD) Symbol(name, len, 1);
assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
} else {
// Allocate to global arena
MutexLocker ml(SymbolTable_lock); // Protect arena
! sym = new (len, arena(), THREAD) Symbol(name, len, PERM_REFCOUNT);
}
return sym;
}
void SymbolTable::initialize_symbols(int arena_alloc_size) {
--- 187,211 ----
MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
SymbolTable::the_table()->_has_work = true;
Service_lock->notify_all();
}
! Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap, TRAPS) {
assert (len <= Symbol::max_length(), "should be checked by caller");
Symbol* sym;
if (DumpSharedSpaces) {
c_heap = false;
}
if (c_heap) {
// refcount starts as 1
! sym = new (len, THREAD) Symbol((const u1*)name, len, 1);
assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
} else {
// Allocate to global arena
MutexLocker ml(SymbolTable_lock); // Protect arena
! sym = new (len, arena(), THREAD) Symbol((const u1*)name, len, PERM_REFCOUNT);
}
return sym;
}
void SymbolTable::initialize_symbols(int arena_alloc_size) {
*** 267,277 ****
SymbolTable::the_table()->_local_table->do_scan(Thread::current(), mpd);
}
Symbol* SymbolTable::lookup_dynamic(const char* name,
int len, unsigned int hash) {
! Symbol* sym = SymbolTable::the_table()->do_lookup((char*)name, len, hash);
assert((sym == NULL) || sym->refcount() != 0, "refcount must not be zero");
return sym;
}
Symbol* SymbolTable::lookup_shared(const char* name,
--- 259,269 ----
SymbolTable::the_table()->_local_table->do_scan(Thread::current(), mpd);
}
Symbol* SymbolTable::lookup_dynamic(const char* name,
int len, unsigned int hash) {
! Symbol* sym = SymbolTable::the_table()->do_lookup(name, len, hash);
assert((sym == NULL) || sym->refcount() != 0, "refcount must not be zero");
return sym;
}
Symbol* SymbolTable::lookup_shared(const char* name,
*** 311,368 ****
Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash);
if (sym == NULL) {
! sym = SymbolTable::the_table()->do_add_if_needed((char*)name, len, hash, true, CHECK_NULL);
}
assert(sym->refcount() != 0, "lookup should have incremented the count");
! assert(sym->equals((char*)name, len), "symbol must be properly initialized");
return sym;
}
Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
! Symbol* found = NULL;
! {
! debug_only(NoSafepointVerifier nsv;)
!
! char* name = (char*)sym->base() + begin;
! int len = end - begin;
! unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
found = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true, THREAD);
}
return found;
}
! class SymbolTableLookupChar : StackObj {
private:
Thread* _thread;
uintx _hash;
int _len;
const char* _str;
- Symbol* _found;
public:
! SymbolTableLookupChar(Thread* thread, const char* key, int len, uintx hash)
! : _thread(thread), _hash(hash), _str(key), _len(len) , _found(NULL) {
! }
uintx get_hash() const {
return _hash;
}
bool equals(Symbol** value, bool* is_dead) {
assert(value != NULL, "expected valid value");
assert(*value != NULL, "value should point to a symbol");
Symbol *sym = *value;
if (sym->equals(_str, _len)) {
if (sym->try_increment_refcount()) {
// something is referencing this symbol now.
- _found = sym;
return true;
} else {
! *is_dead = (sym->refcount() == 0);
return false;
}
} else {
return false;
}
}
};
--- 303,358 ----
Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash);
if (sym == NULL) {
! sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true, CHECK_NULL);
}
assert(sym->refcount() != 0, "lookup should have incremented the count");
! assert(sym->equals(name, len), "symbol must be properly initialized");
return sym;
}
Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
! assert(sym->refcount() != 0, "require a valid symbol");
! const char* name = (const char*)sym->base() + begin;
! int len = end - begin;
! unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
! Symbol* found = SymbolTable::the_table()->lookup_common(name, len, hash);
! if (found == NULL) {
found = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true, THREAD);
}
return found;
}
! class SymbolTableLookup : StackObj {
private:
Thread* _thread;
uintx _hash;
int _len;
const char* _str;
public:
! SymbolTableLookup(Thread* thread, const char* key, int len, uintx hash)
! : _thread(thread), _hash(hash), _str(key), _len(len) {}
uintx get_hash() const {
return _hash;
}
bool equals(Symbol** value, bool* is_dead) {
assert(value != NULL, "expected valid value");
assert(*value != NULL, "value should point to a symbol");
Symbol *sym = *value;
if (sym->equals(_str, _len)) {
if (sym->try_increment_refcount()) {
// something is referencing this symbol now.
return true;
} else {
! assert(sym->refcount() == 0, "expected dead symbol");
! *is_dead = true;
return false;
}
} else {
+ *is_dead = (sym->refcount() == 0);
return false;
}
}
};
*** 378,392 ****
Symbol* get_res_sym() {
return _return;
}
};
! Symbol* SymbolTable::do_lookup(char* name, int len, uintx hash) {
Thread* thread = Thread::current();
! SymbolTableLookupChar lookup(thread, name, len, hash);
SymbolTableGet stg;
! bool rehash_warning;
_local_table->get(thread, lookup, stg, &rehash_warning);
if (rehash_warning) {
_needs_rehashing = true;
}
Symbol* sym = stg.get_res_sym();
--- 368,382 ----
Symbol* get_res_sym() {
return _return;
}
};
! Symbol* SymbolTable::do_lookup(const char* name, int len, uintx hash) {
Thread* thread = Thread::current();
! SymbolTableLookup lookup(thread, name, len, hash);
SymbolTableGet stg;
! bool rehash_warning = false;
_local_table->get(thread, lookup, stg, &rehash_warning);
if (rehash_warning) {
_needs_rehashing = true;
}
Symbol* sym = stg.get_res_sym();
*** 435,453 ****
void SymbolTable::add(ClassLoaderData* loader_data, const constantPoolHandle& cp,
int names_count, const char** names, int* lengths,
int* cp_indices, unsigned int* hashValues, TRAPS) {
bool c_heap = !loader_data->is_the_null_class_loader_data();
! for (int i=0; i<names_count; i++) {
! char *name = (char*)names[i];
int len = lengths[i];
unsigned int hash = hashValues[i];
Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash);
if (sym == NULL) {
sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap, CHECK);
}
! assert(sym->refcount()!=0, "lookup should have incremented the count");
cp->symbol_at_put(cp_indices[i], sym);
}
}
class SymbolTableCreateEntry : public StackObj {
--- 425,443 ----
void SymbolTable::add(ClassLoaderData* loader_data, const constantPoolHandle& cp,
int names_count, const char** names, int* lengths,
int* cp_indices, unsigned int* hashValues, TRAPS) {
bool c_heap = !loader_data->is_the_null_class_loader_data();
! for (int i = 0; i < names_count; i++) {
! const char *name = names[i];
int len = lengths[i];
unsigned int hash = hashValues[i];
Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash);
if (sym == NULL) {
sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap, CHECK);
}
! assert(sym->refcount() != 0, "lookup should have incremented the count");
cp->symbol_at_put(cp_indices[i], sym);
}
}
class SymbolTableCreateEntry : public StackObj {
*** 457,488 ****
int _len;
bool _heap;
Symbol* _return;
Symbol* _created;
#ifdef ASSERT
- void _assert_for_name(Symbol* sym, const char* where) const {
assert(sym->utf8_length() == _len, "%s [%d,%d]", where, sym->utf8_length(), _len);
! for (int i=0; i<_len; i++) {
assert(sym->byte_at(i) == _name[i],
"%s [%d,%d,%d]", where, i, sym->byte_at(i), _name[i]);
}
- }
#endif
public:
SymbolTableCreateEntry(Thread* thread, const char* name, int len, bool heap)
: _thread(thread), _name(name) , _len(len), _heap(heap), _return(NULL) , _created(NULL) {
assert(_name != NULL, "expected valid name");
}
Symbol* operator()() {
! _created = SymbolTable::the_table()->allocate_symbol((const u1*)_name, _len, _heap, _thread);
assert(_created != NULL, "expected created symbol");
! #ifdef ASSERT
! _assert_for_name(_created, "operator()()");
! #endif
! assert(_created->equals((char*)_name, _len),
"symbol must be properly initialized [%p,%d,%d]", _name, _len, (int)_heap);
return _created;
}
void operator()(bool inserted, Symbol** value) {
assert(value != NULL, "expected valid value");
--- 447,476 ----
int _len;
bool _heap;
Symbol* _return;
Symbol* _created;
+ void assert_for_name(Symbol* sym, const char* where) const {
#ifdef ASSERT
assert(sym->utf8_length() == _len, "%s [%d,%d]", where, sym->utf8_length(), _len);
! for (int i = 0; i < _len; i++) {
assert(sym->byte_at(i) == _name[i],
"%s [%d,%d,%d]", where, i, sym->byte_at(i), _name[i]);
}
#endif
+ }
public:
SymbolTableCreateEntry(Thread* thread, const char* name, int len, bool heap)
: _thread(thread), _name(name) , _len(len), _heap(heap), _return(NULL) , _created(NULL) {
assert(_name != NULL, "expected valid name");
}
Symbol* operator()() {
! _created = SymbolTable::the_table()->allocate_symbol(_name, _len, _heap, _thread);
assert(_created != NULL, "expected created symbol");
! assert_for_name(_created, "operator()()");
! assert(_created->equals(_name, _len),
"symbol must be properly initialized [%p,%d,%d]", _name, _len, (int)_heap);
return _created;
}
void operator()(bool inserted, Symbol** value) {
assert(value != NULL, "expected valid value");
*** 498,524 ****
_created->decrement_refcount();
assert(_created->refcount() == 0, "expected dead symbol");
}
}
_return = *value;
! #ifdef ASSERT
! _assert_for_name(_return, "operator()");
! #endif
}
Symbol* get_new_sym() const {
! #ifdef ASSERT
! _assert_for_name(_return, "get_new_sym");
! #endif
return _return;
}
};
! Symbol* SymbolTable::do_add_if_needed(char* name, int len, uintx hash, bool heap, TRAPS) {
! SymbolTableLookupChar lookup(THREAD, name, len, hash);
SymbolTableCreateEntry stce(THREAD, name, len, heap);
! bool rehash_warning;
! bool clean_hint;
_local_table->get_insert_lazy(THREAD, lookup, stce, stce, &rehash_warning, &clean_hint);
if (rehash_warning) {
_needs_rehashing = true;
}
if (clean_hint) {
--- 486,508 ----
_created->decrement_refcount();
assert(_created->refcount() == 0, "expected dead symbol");
}
}
_return = *value;
! assert_for_name(_return, "operator()");
}
Symbol* get_new_sym() const {
! assert_for_name(_return, "get_new_sym");
return _return;
}
};
! Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, bool heap, TRAPS) {
! SymbolTableLookup lookup(THREAD, name, len, hash);
SymbolTableCreateEntry stce(THREAD, name, len, heap);
! bool rehash_warning = false;
! bool clean_hint = false;
_local_table->get_insert_lazy(THREAD, lookup, stce, stce, &rehash_warning, &clean_hint);
if (rehash_warning) {
_needs_rehashing = true;
}
if (clean_hint) {
*** 538,548 ****
Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
unsigned int hash = 0;
int len = (int)strlen(name);
Symbol* sym = SymbolTable::lookup_only(name, len, hash);
if (sym == NULL) {
! sym = SymbolTable::the_table()->do_add_if_needed((char*)name, len, hash, false, CHECK_NULL);
}
if (sym->refcount() != PERM_REFCOUNT) {
sym->increment_refcount();
_log_trace_symboltable_helper(sym, "Asked for a permanent symbol, but got a regular one");
}
--- 522,532 ----
Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
unsigned int hash = 0;
int len = (int)strlen(name);
Symbol* sym = SymbolTable::lookup_only(name, len, hash);
if (sym == NULL) {
! sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, false, CHECK_NULL);
}
if (sym->refcount() != PERM_REFCOUNT) {
sym->increment_refcount();
_log_trace_symboltable_helper(sym, "Asked for a permanent symbol, but got a regular one");
}
*** 568,578 ****
public:
bool operator()(Symbol** value) {
guarantee(value != NULL, "expected valid value");
guarantee(*value != NULL, "value should point to a symbol");
Symbol* sym = *value;
! guarantee(sym->equals((char*)sym->bytes(), sym->utf8_length()),
"symbol must be internally consistent");
return true;
};
};
--- 552,562 ----
public:
bool operator()(Symbol** value) {
guarantee(value != NULL, "expected valid value");
guarantee(*value != NULL, "value should point to a symbol");
Symbol* sym = *value;
! guarantee(sym->equals((const char*)sym->bytes(), sym->utf8_length()),
"symbol must be internally consistent");
return true;
};
};
*** 623,637 ****
CopyToArchive(CompactSymbolTableWriter* writer) : _writer(writer) {}
bool operator()(Symbol** value) {
assert(value != NULL, "expected valid value");
assert(*value != NULL, "value should point to a symbol");
Symbol* sym = *value;
! unsigned int fixed_hash = hash_shared_symbol((char*)sym->bytes(), sym->utf8_length());
if (fixed_hash == 0) {
return true;
}
! assert(fixed_hash == hash_symbol((char*)sym->bytes(), sym->utf8_length(), false),
"must not rehash during dumping");
// add to the compact table
_writer->add(fixed_hash, sym);
--- 607,621 ----
CopyToArchive(CompactSymbolTableWriter* writer) : _writer(writer) {}
bool operator()(Symbol** value) {
assert(value != NULL, "expected valid value");
assert(*value != NULL, "value should point to a symbol");
Symbol* sym = *value;
! unsigned int fixed_hash = hash_shared_symbol((const char*)sym->bytes(), sym->utf8_length());
if (fixed_hash == 0) {
return true;
}
! assert(fixed_hash == hash_symbol((const char*)sym->bytes(), sym->utf8_length(), false),
"must not rehash during dumping");
// add to the compact table
_writer->add(fixed_hash, sym);
*** 645,655 ****
}
void SymbolTable::write_to_archive() {
_shared_table.reset();
! int num_buckets = (SymbolTable::the_table()->_items / SharedSymbolTableBucketSize);
// calculation of num_buckets can result in zero buckets, we need at least one
CompactSymbolTableWriter writer(num_buckets > 1 ? num_buckets : 1,
&MetaspaceShared::stats()->symbol);
copy_shared_symbol_table(&writer);
writer.dump(&_shared_table);
--- 629,639 ----
}
void SymbolTable::write_to_archive() {
_shared_table.reset();
! int num_buckets = (SymbolTable::the_table()->_items_count / SharedSymbolTableBucketSize);
// calculation of num_buckets can result in zero buckets, we need at least one
CompactSymbolTableWriter writer(num_buckets > 1 ? num_buckets : 1,
&MetaspaceShared::stats()->symbol);
copy_shared_symbol_table(&writer);
writer.dump(&_shared_table);
*** 713,727 ****
bool operator()(Symbol** value) {
assert(value != NULL, "expected valid value");
assert(*value != NULL, "value should point to a symbol");
_processed++;
Symbol *sym = *value;
! if (sym->refcount() == 0) {
! return true;
! } else {
! return false;
! }
}
};
void SymbolTable::clean_dead_entries(JavaThread* jt) {
SymbolTableHash::BulkDeleteTask bdt(_local_table);
--- 697,707 ----
bool operator()(Symbol** value) {
assert(value != NULL, "expected valid value");
assert(*value != NULL, "value should point to a symbol");
_processed++;
Symbol *sym = *value;
! return (sym->refcount() == 0);
}
};
void SymbolTable::clean_dead_entries(JavaThread* jt) {
SymbolTableHash::BulkDeleteTask bdt(_local_table);
*** 742,752 ****
}
SymbolTable::the_table()->set_item_clean_count(0);
bdt.done(jt);
}
! Atomic::add(stdc._processed, &_symbols_counted);
log_debug(symboltable)("Cleaned " INT32_FORMAT " of " INT32_FORMAT,
stdd._deleted, stdc._processed);
}
--- 722,732 ----
}
SymbolTable::the_table()->set_item_clean_count(0);
bdt.done(jt);
}
! Atomic::add((size_t)stdc._processed, &_symbols_counted);
log_debug(symboltable)("Cleaned " INT32_FORMAT " of " INT32_FORMAT,
stdd._deleted, stdc._processed);
}
*** 876,908 ****
#ifndef PRODUCT
class HistogramIterator : StackObj {
public:
! static const int results_length = 100;
! int counts[results_length];
! int sizes[results_length];
! int total_size;
! int total_count;
! int total_length;
! int max_length;
! int out_of_range_count;
! int out_of_range_size;
HistogramIterator() : total_size(0), total_count(0), total_length(0),
max_length(0), out_of_range_count(0), out_of_range_size(0) {
// initialize results to zero
! for (int i = 0; i < results_length; i++) {
counts[i] = 0;
sizes[i] = 0;
}
}
bool operator()(Symbol** value) {
assert(value != NULL, "expected valid value");
assert(*value != NULL, "value should point to a symbol");
Symbol* sym = *value;
! int size = sym->size();
! int len = sym->utf8_length();
if (len < results_length) {
counts[len]++;
sizes[len] += size;
} else {
out_of_range_count++;
--- 856,888 ----
#ifndef PRODUCT
class HistogramIterator : StackObj {
public:
! static const size_t results_length = 100;
! size_t counts[results_length];
! size_t sizes[results_length];
! size_t total_size;
! size_t total_count;
! size_t total_length;
! size_t max_length;
! size_t out_of_range_count;
! size_t out_of_range_size;
HistogramIterator() : total_size(0), total_count(0), total_length(0),
max_length(0), out_of_range_count(0), out_of_range_size(0) {
// initialize results to zero
! for (size_t i = 0; i < results_length; i++) {
counts[i] = 0;
sizes[i] = 0;
}
}
bool operator()(Symbol** value) {
assert(value != NULL, "expected valid value");
assert(*value != NULL, "value should point to a symbol");
Symbol* sym = *value;
! size_t size = sym->size();
! size_t len = sym->utf8_length();
if (len < results_length) {
counts[len]++;
sizes[len] += size;
} else {
out_of_range_count++;
*** 916,952 ****
return true;
};
};
void SymbolTable::print_histogram() {
HistogramIterator hi;
! SymbolTable::the_table()->_local_table->do_scan(Thread::current(), hi);
tty->print_cr("Symbol Table Histogram:");
! tty->print_cr(" Total number of symbols %7d", hi.total_count);
! tty->print_cr(" Total size in memory %7dK",
! (hi.total_size*wordSize)/1024);
! tty->print_cr(" Total counted %7d", _symbols_counted);
! tty->print_cr(" Total removed %7d", _symbols_removed);
! if (_symbols_counted > 0) {
tty->print_cr(" Percent removed %3.2f",
! ((float)_symbols_removed/(float)_symbols_counted)* 100);
}
! tty->print_cr(" Reference counts %7d", Symbol::_total_count);
! tty->print_cr(" Symbol arena used " SIZE_FORMAT_W(7) "K", arena()->used()/1024);
! tty->print_cr(" Symbol arena size " SIZE_FORMAT_W(7) "K", arena()->size_in_bytes()/1024);
! tty->print_cr(" Total symbol length %7d", hi.total_length);
! tty->print_cr(" Maximum symbol length %7d", hi.max_length);
! tty->print_cr(" Average symbol length %7.2f", ((float) hi.total_length / (float) hi.total_count));
tty->print_cr(" Symbol length histogram:");
tty->print_cr(" %6s %10s %10s", "Length", "#Symbols", "Size");
! for (int i = 0; i < hi.results_length; i++) {
if (hi.counts[i] > 0) {
! tty->print_cr(" %6d %10d %10dK", i, hi.counts[i], (hi.sizes[i]*wordSize)/1024);
}
}
! tty->print_cr(" >=%6d %10d %10dK\n", hi.results_length,
! hi.out_of_range_count, (hi.out_of_range_size*wordSize)/1024);
}
#endif // PRODUCT
// Utility for dumping symbols
SymboltableDCmd::SymboltableDCmd(outputStream* output, bool heap) :
--- 896,934 ----
return true;
};
};
void SymbolTable::print_histogram() {
+ SymbolTable* st = SymbolTable::the_table();
HistogramIterator hi;
! st->_local_table->do_scan(Thread::current(), hi);
tty->print_cr("Symbol Table Histogram:");
! tty->print_cr(" Total number of symbols " SIZE_FORMAT_W(7), hi.total_count);
! tty->print_cr(" Total size in memory " SIZE_FORMAT_W(7) "K",
! (hi.total_size * wordSize) / 1024);
! tty->print_cr(" Total counted " SIZE_FORMAT_W(7), st->_symbols_counted);
! tty->print_cr(" Total removed " SIZE_FORMAT_W(7), st->_symbols_removed);
! if (SymbolTable::the_table()->_symbols_counted > 0) {
tty->print_cr(" Percent removed %3.2f",
! ((float)st->_symbols_removed / st->_symbols_counted) * 100);
}
! tty->print_cr(" Reference counts " SIZE_FORMAT_W(7), Symbol::_total_count);
! tty->print_cr(" Symbol arena used " SIZE_FORMAT_W(7) "K", arena()->used() / 1024);
! tty->print_cr(" Symbol arena size " SIZE_FORMAT_W(7) "K", arena()->size_in_bytes() / 1024);
! tty->print_cr(" Total symbol length " SIZE_FORMAT_W(7), hi.total_length);
! tty->print_cr(" Maximum symbol length " SIZE_FORMAT_W(7), hi.max_length);
! tty->print_cr(" Average symbol length %7.2f", ((float)hi.total_length / hi.total_count));
tty->print_cr(" Symbol length histogram:");
tty->print_cr(" %6s %10s %10s", "Length", "#Symbols", "Size");
! for (size_t i = 0; i < hi.results_length; i++) {
if (hi.counts[i] > 0) {
! tty->print_cr(" " SIZE_FORMAT_W(6) " " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) "K",
! i, hi.counts[i], (hi.sizes[i] * wordSize) / 1024);
}
}
! tty->print_cr(" >=" SIZE_FORMAT_W(6) " " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) "K\n",
! hi.results_length, hi.out_of_range_count, (hi.out_of_range_size*wordSize) / 1024);
}
#endif // PRODUCT
// Utility for dumping symbols
SymboltableDCmd::SymboltableDCmd(outputStream* output, bool heap) :
< prev index next >