610 _st->cr(); 611 return true; 612 }; 613 }; 614 615 void SymbolTable::dump(outputStream* st, bool verbose) { 616 if (!verbose) { 617 SymbolTable::the_table()->print_table_statistics(st, "SymbolTable"); 618 } else { 619 Thread* thr = Thread::current(); 620 ResourceMark rm(thr); 621 st->print_cr("VERSION: 1.1"); 622 DumpSymbol ds(thr, st); 623 if (!SymbolTable::the_table()->_local_table->try_scan(thr, ds)) { 624 log_info(symboltable)("dump unavailable at this moment"); 625 } 626 } 627 } 628 629 #if INCLUDE_CDS 630 class CompactSymbolTableWriter: public CompactHashtableWriter { 631 public: 632 CompactSymbolTableWriter(int num_buckets, CompactHashtableStats* stats) : 633 CompactHashtableWriter(num_buckets, stats) {} 634 void add(unsigned int hash, Symbol *symbol) { 635 uintx deltax = MetaspaceShared::object_delta(symbol); 636 // When the symbols are stored into the archive, we already check that 637 // they won't be more than MAX_SHARED_DELTA from the base address, or 638 // else the dumping would have been aborted. 639 assert(deltax <= MAX_SHARED_DELTA, "must not be"); 640 u4 delta = u4(deltax); 641 642 CompactHashtableWriter::add(hash, delta); 643 } 644 }; 645 646 struct CopyToArchive : StackObj { 647 CompactSymbolTableWriter* _writer; 648 CopyToArchive(CompactSymbolTableWriter* writer) : _writer(writer) {} 649 bool operator()(Symbol** value) { 650 assert(value != NULL, "expected valid value"); 651 assert(*value != NULL, "value should point to a symbol"); 652 Symbol* sym = *value; 653 unsigned int fixed_hash = hash_shared_symbol((const char*)sym->bytes(), sym->utf8_length()); 654 if (fixed_hash == 0) { 655 return true; 656 } 657 assert(fixed_hash == hash_symbol((const char*)sym->bytes(), sym->utf8_length(), false), 658 "must not rehash during dumping"); 659 660 // add to the compact table 661 _writer->add(fixed_hash, sym); 662 return true; 663 } 664 }; 665 666 void SymbolTable::copy_shared_symbol_table(CompactSymbolTableWriter* writer) { 667 CopyToArchive copy(writer); 668 SymbolTable::the_table()->_local_table->do_scan(Thread::current(), copy); 669 } 670 671 void SymbolTable::write_to_archive() { 672 _shared_table.reset(); 673 674 int num_buckets = (int)(SymbolTable::the_table()->_items_count / SharedSymbolTableBucketSize); 675 // calculation of num_buckets can result in zero buckets, we need at least one 676 CompactSymbolTableWriter writer(num_buckets > 1 ? num_buckets : 1, 677 &MetaspaceShared::stats()->symbol); 678 copy_shared_symbol_table(&writer); 679 writer.dump(&_shared_table, "symbol"); 680 681 // Verify table is correct 682 Symbol* sym = vmSymbols::java_lang_Object(); 683 const char* name = (const char*)sym->bytes(); 684 int len = sym->utf8_length(); 685 unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash); 686 assert(sym == _shared_table.lookup(name, hash, len), "sanity"); 687 } 688 689 void SymbolTable::serialize(SerializeClosure* soc) { 690 _shared_table.serialize(soc); 691 692 if (soc->writing()) { 693 // Sanity. Make sure we don't use the shared table at dump time 694 _shared_table.reset(); 695 } 696 } | 610 _st->cr(); 611 return true; 612 }; 613 }; 614 615 void SymbolTable::dump(outputStream* st, bool verbose) { 616 if (!verbose) { 617 SymbolTable::the_table()->print_table_statistics(st, "SymbolTable"); 618 } else { 619 Thread* thr = Thread::current(); 620 ResourceMark rm(thr); 621 st->print_cr("VERSION: 1.1"); 622 DumpSymbol ds(thr, st); 623 if (!SymbolTable::the_table()->_local_table->try_scan(thr, ds)) { 624 log_info(symboltable)("dump unavailable at this moment"); 625 } 626 } 627 } 628 629 #if INCLUDE_CDS 630 struct CopyToArchive : StackObj { 631 CompactHashtableWriter* _writer; 632 CopyToArchive(CompactHashtableWriter* writer) : _writer(writer) {} 633 bool operator()(Symbol** value) { 634 assert(value != NULL, "expected valid value"); 635 assert(*value != NULL, "value should point to a symbol"); 636 Symbol* sym = *value; 637 unsigned int fixed_hash = hash_shared_symbol((const char*)sym->bytes(), sym->utf8_length()); 638 assert(fixed_hash == hash_symbol((const char*)sym->bytes(), sym->utf8_length(), false), 639 "must not rehash during dumping"); 640 641 uintx deltax = MetaspaceShared::object_delta(sym); 642 // When the symbols are stored into the archive, we already check that 643 // they won't be more than MAX_SHARED_DELTA from the base address, or 644 // else the dumping would have been aborted. 645 assert(deltax <= MAX_SHARED_DELTA, "must not be"); 646 u4 delta = u4(deltax); 647 648 // add to the compact table 649 _writer->add(fixed_hash, delta); 650 return true; 651 } 652 }; 653 654 void SymbolTable::copy_shared_symbol_table(CompactHashtableWriter* writer) { 655 CopyToArchive copy(writer); 656 SymbolTable::the_table()->_local_table->do_scan(Thread::current(), copy); 657 } 658 659 void SymbolTable::write_to_archive() { 660 _shared_table.reset(); 661 662 int num_buckets = CompactHashtableWriter::default_num_buckets( 663 SymbolTable::the_table()->_items_count); 664 CompactHashtableWriter writer(num_buckets, 665 &MetaspaceShared::stats()->symbol); 666 copy_shared_symbol_table(&writer); 667 writer.dump(&_shared_table, "symbol"); 668 669 // Verify table is correct 670 Symbol* sym = vmSymbols::java_lang_Object(); 671 const char* name = (const char*)sym->bytes(); 672 int len = sym->utf8_length(); 673 unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash); 674 assert(sym == _shared_table.lookup(name, hash, len), "sanity"); 675 } 676 677 void SymbolTable::serialize(SerializeClosure* soc) { 678 _shared_table.serialize(soc); 679 680 if (soc->writing()) { 681 // Sanity. Make sure we don't use the shared table at dump time 682 _shared_table.reset(); 683 } 684 } |