15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/altHashing.hpp" 27 #include "classfile/compactHashtable.inline.hpp" 28 #include "classfile/javaClasses.hpp" 29 #include "classfile/symbolTable.hpp" 30 #include "classfile/systemDictionary.hpp" 31 #include "gc/shared/collectedHeap.inline.hpp" 32 #include "gc/shared/gcLocker.inline.hpp" 33 #include "memory/allocation.inline.hpp" 34 #include "memory/filemap.hpp" 35 #include "memory/resourceArea.hpp" 36 #include "oops/oop.inline.hpp" 37 #include "runtime/atomic.hpp" 38 #include "runtime/mutexLocker.hpp" 39 #include "utilities/hashtable.inline.hpp" 40 41 // -------------------------------------------------------------------------- 42 // the number of buckets a thread claims 43 const int ClaimChunkSize = 32; 44 45 SymbolTable* SymbolTable::_the_table = NULL; 46 // Static arena for symbols that are not deallocated 47 Arena* SymbolTable::_arena = NULL; 48 bool SymbolTable::_needs_rehashing = false; 49 bool SymbolTable::_lookup_shared_first = false; 50 51 CompactHashtable<Symbol*, char> SymbolTable::_shared_table; 52 53 Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) { 54 assert (len <= Symbol::max_length(), "should be checked by caller"); 55 56 Symbol* sym; 57 58 if (DumpSharedSpaces) { 59 // Allocate all symbols to CLD shared metaspace 60 sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, PERM_REFCOUNT); 61 } else if (c_heap) { 62 // refcount starts as 1 63 sym = new (len, THREAD) Symbol(name, len, 1); 64 assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted"); 65 } else { 66 // Allocate to global arena 67 sym = new (len, arena(), THREAD) Symbol(name, len, PERM_REFCOUNT); 68 } 69 return sym; 70 } 71 72 void SymbolTable::initialize_symbols(int arena_alloc_size) { 73 // Initialize the arena for global symbols, size passed in depends on CDS. 74 if (arena_alloc_size == 0) { 75 _arena = new (mtSymbol) Arena(mtSymbol); 76 } else { 77 _arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size); 78 } 79 } 80 81 // Call function for all symbols in the symbol table. 82 void SymbolTable::symbols_do(SymbolClosure *cl) { 83 // all symbols from shared table 84 _shared_table.symbols_do(cl); 85 86 // all symbols from the dynamic table 87 const int n = the_table()->table_size(); 88 for (int i = 0; i < n; i++) { 89 for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); 90 p != NULL; 91 p = p->next()) { 92 cl->do_symbol(p->literal_addr()); 93 } 94 } 95 } 96 97 int SymbolTable::_symbols_removed = 0; 98 int SymbolTable::_symbols_counted = 0; 99 volatile int SymbolTable::_parallel_claimed_idx = 0; 100 101 void SymbolTable::buckets_unlink(int start_idx, int end_idx, BucketUnlinkContext* context) { 102 for (int i = start_idx; i < end_idx; ++i) { 103 HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i); 104 HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i); 105 while (entry != NULL) { 106 // Shared entries are normally at the end of the bucket and if we run into 107 // a shared entry, then there is nothing more to remove. However, if we 108 // have rehashed the table, then the shared entries are no longer at the 109 // end of the bucket. 110 if (entry->is_shared() && !use_alternate_hashcode()) { 111 break; 112 } 113 Symbol* s = entry->literal(); 114 context->_num_processed++; 115 assert(s != NULL, "just checking"); 116 // If reference count is zero, remove. 550 551 void SymbolTable::dump(outputStream* st, bool verbose) { 552 if (!verbose) { 553 the_table()->dump_table(st, "SymbolTable"); 554 } else { 555 st->print_cr("VERSION: 1.0"); 556 for (int i = 0; i < the_table()->table_size(); ++i) { 557 HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); 558 for ( ; p != NULL; p = p->next()) { 559 Symbol* s = (Symbol*)(p->literal()); 560 const char* utf8_string = (const char*)s->bytes(); 561 int utf8_length = s->utf8_length(); 562 st->print("%d %d: ", utf8_length, s->refcount()); 563 HashtableTextDump::put_utf8(st, utf8_string, utf8_length); 564 st->cr(); 565 } 566 } 567 } 568 } 569 570 void SymbolTable::serialize(SerializeClosure* soc) { 571 #if INCLUDE_CDS 572 _shared_table.reset(); 573 if (soc->writing()) { 574 int num_buckets = the_table()->number_of_entries() / 575 SharedSymbolTableBucketSize; 576 CompactSymbolTableWriter writer(num_buckets, 577 &MetaspaceShared::stats()->symbol); 578 for (int i = 0; i < the_table()->table_size(); ++i) { 579 HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); 580 for ( ; p != NULL; p = p->next()) { 581 Symbol* s = (Symbol*)(p->literal()); 582 unsigned int fixed_hash = hash_shared_symbol((char*)s->bytes(), s->utf8_length()); 583 assert(fixed_hash == p->hash(), "must not rehash during dumping"); 584 writer.add(fixed_hash, s); 585 } 586 } 587 588 writer.dump(&_shared_table); 589 } 590 591 _shared_table.set_type(CompactHashtable<Symbol*, char>::_symbol_table); 592 _shared_table.serialize(soc); 593 594 if (soc->writing()) { 595 // Verify table is correct 596 Symbol* sym = vmSymbols::java_lang_Object(); 597 const char* name = (const char*)sym->bytes(); 598 int len = sym->utf8_length(); 599 unsigned int hash = hash_symbol(name, len); 600 assert(sym == _shared_table.lookup(name, hash, len), "sanity"); 601 602 // Sanity. Make sure we don't use the shared table at dump time 603 _shared_table.reset(); 604 } 605 #endif 606 } 607 608 //--------------------------------------------------------------------------- 609 // Non-product code 610 611 #ifndef PRODUCT 612 613 void SymbolTable::print_histogram() { 614 MutexLocker ml(SymbolTable_lock); 615 const int results_length = 100; 616 int counts[results_length]; 617 int sizes[results_length]; 618 int i,j; 619 620 // initialize results to zero 621 for (j = 0; j < results_length; j++) { | 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/altHashing.hpp" 27 #include "classfile/compactHashtable.inline.hpp" 28 #include "classfile/javaClasses.hpp" 29 #include "classfile/symbolTable.hpp" 30 #include "classfile/systemDictionary.hpp" 31 #include "gc/shared/collectedHeap.inline.hpp" 32 #include "gc/shared/gcLocker.inline.hpp" 33 #include "memory/allocation.inline.hpp" 34 #include "memory/filemap.hpp" 35 #include "memory/metaspaceClosure.hpp" 36 #include "memory/resourceArea.hpp" 37 #include "oops/oop.inline.hpp" 38 #include "runtime/atomic.hpp" 39 #include "runtime/mutexLocker.hpp" 40 #include "utilities/hashtable.inline.hpp" 41 42 // -------------------------------------------------------------------------- 43 // the number of buckets a thread claims 44 const int ClaimChunkSize = 32; 45 46 SymbolTable* SymbolTable::_the_table = NULL; 47 // Static arena for symbols that are not deallocated 48 Arena* SymbolTable::_arena = NULL; 49 bool SymbolTable::_needs_rehashing = false; 50 bool SymbolTable::_lookup_shared_first = false; 51 52 CompactHashtable<Symbol*, char> SymbolTable::_shared_table; 53 54 Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) { 55 assert (len <= Symbol::max_length(), "should be checked by caller"); 56 57 Symbol* sym; 58 59 if (DumpSharedSpaces) { 60 c_heap = false; 61 } 62 if (c_heap) { 63 // refcount starts as 1 64 sym = new (len, THREAD) Symbol(name, len, 1); 65 assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted"); 66 } else { 67 // Allocate to global arena 68 sym = new (len, arena(), THREAD) Symbol(name, len, PERM_REFCOUNT); 69 } 70 return sym; 71 } 72 73 void SymbolTable::initialize_symbols(int arena_alloc_size) { 74 // Initialize the arena for global symbols, size passed in depends on CDS. 75 if (arena_alloc_size == 0) { 76 _arena = new (mtSymbol) Arena(mtSymbol); 77 } else { 78 _arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size); 79 } 80 } 81 82 // Call function for all symbols in the symbol table. 83 void SymbolTable::symbols_do(SymbolClosure *cl) { 84 if (!DumpSharedSpaces) { 85 // all symbols from shared table 86 _shared_table.symbols_do(cl); 87 } 88 89 // all symbols from the dynamic table 90 const int n = the_table()->table_size(); 91 for (int i = 0; i < n; i++) { 92 for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); 93 p != NULL; 94 p = p->next()) { 95 cl->do_symbol(p->literal_addr()); 96 } 97 } 98 } 99 100 void SymbolTable::metaspace_pointers_do(MetaspaceClosure* it) { 101 assert(DumpSharedSpaces, "called only during dump time"); 102 const int n = the_table()->table_size(); 103 for (int i = 0; i < n; i++) { 104 for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); 105 p != NULL; 106 p = p->next()) { 107 it->push(p->literal_addr()); 108 } 109 } 110 } 111 112 int SymbolTable::_symbols_removed = 0; 113 int SymbolTable::_symbols_counted = 0; 114 volatile int SymbolTable::_parallel_claimed_idx = 0; 115 116 void SymbolTable::buckets_unlink(int start_idx, int end_idx, BucketUnlinkContext* context) { 117 for (int i = start_idx; i < end_idx; ++i) { 118 HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i); 119 HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i); 120 while (entry != NULL) { 121 // Shared entries are normally at the end of the bucket and if we run into 122 // a shared entry, then there is nothing more to remove. However, if we 123 // have rehashed the table, then the shared entries are no longer at the 124 // end of the bucket. 125 if (entry->is_shared() && !use_alternate_hashcode()) { 126 break; 127 } 128 Symbol* s = entry->literal(); 129 context->_num_processed++; 130 assert(s != NULL, "just checking"); 131 // If reference count is zero, remove. 565 566 void SymbolTable::dump(outputStream* st, bool verbose) { 567 if (!verbose) { 568 the_table()->dump_table(st, "SymbolTable"); 569 } else { 570 st->print_cr("VERSION: 1.0"); 571 for (int i = 0; i < the_table()->table_size(); ++i) { 572 HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); 573 for ( ; p != NULL; p = p->next()) { 574 Symbol* s = (Symbol*)(p->literal()); 575 const char* utf8_string = (const char*)s->bytes(); 576 int utf8_length = s->utf8_length(); 577 st->print("%d %d: ", utf8_length, s->refcount()); 578 HashtableTextDump::put_utf8(st, utf8_string, utf8_length); 579 st->cr(); 580 } 581 } 582 } 583 } 584 585 void SymbolTable::write_to_archive() { 586 #if INCLUDE_CDS 587 _shared_table.reset(); 588 589 int num_buckets = the_table()->number_of_entries() / 590 SharedSymbolTableBucketSize; 591 CompactSymbolTableWriter writer(num_buckets, 592 &MetaspaceShared::stats()->symbol); 593 for (int i = 0; i < the_table()->table_size(); ++i) { 594 HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); 595 for ( ; p != NULL; p = p->next()) { 596 Symbol* s = (Symbol*)(p->literal()); 597 unsigned int fixed_hash = hash_shared_symbol((char*)s->bytes(), s->utf8_length()); 598 assert(fixed_hash == p->hash(), "must not rehash during dumping"); 599 writer.add(fixed_hash, s); 600 } 601 } 602 603 writer.dump(&_shared_table); 604 605 // Verify table is correct 606 Symbol* sym = vmSymbols::java_lang_Object(); 607 const char* name = (const char*)sym->bytes(); 608 int len = sym->utf8_length(); 609 unsigned int hash = hash_symbol(name, len); 610 assert(sym == _shared_table.lookup(name, hash, len), "sanity"); 611 #endif 612 } 613 614 void SymbolTable::serialize(SerializeClosure* soc) { 615 #if INCLUDE_CDS 616 _shared_table.set_type(CompactHashtable<Symbol*, char>::_symbol_table); 617 _shared_table.serialize(soc); 618 619 if (soc->writing()) { 620 // Sanity. Make sure we don't use the shared table at dump time 621 _shared_table.reset(); 622 } 623 #endif 624 } 625 626 //--------------------------------------------------------------------------- 627 // Non-product code 628 629 #ifndef PRODUCT 630 631 void SymbolTable::print_histogram() { 632 MutexLocker ml(SymbolTable_lock); 633 const int results_length = 100; 634 int counts[results_length]; 635 int sizes[results_length]; 636 int i,j; 637 638 // initialize results to zero 639 for (j = 0; j < results_length; j++) { |