< 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 >