--- old/src/hotspot/share/classfile/symbolTable.cpp 2018-09-18 21:27:56.153320861 -0700 +++ new/src/hotspot/share/classfile/symbolTable.cpp 2018-09-18 21:27:55.889310693 -0700 @@ -24,11 +24,12 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" -#include "classfile/compactHashtable.inline.hpp" +#include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "memory/allocation.inline.hpp" #include "memory/metaspaceClosure.hpp" +#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" @@ -56,8 +57,27 @@ #define ON_STACK_BUFFER_LENGTH 128 // -------------------------------------------------------------------------- +inline Symbol* read_symbol_from_compact_hashtable(address base_address, u4 offset) { + return (Symbol*)(base_address + offset); +} + +inline bool symbol_equals_compact_hashtable_entry(Symbol* value, const char* key, int len) { + if (value->equals(key, len)) { + assert(value->refcount() == PERM_REFCOUNT, "must be shared"); + return true; + } else { + return false; + } +} + +static CompactHashtable< + const char*, Symbol*, + read_symbol_from_compact_hashtable, + symbol_equals_compact_hashtable_entry +> _shared_table; + +// -------------------------------------------------------------------------- SymbolTable* SymbolTable::_the_table = NULL; -CompactHashtable SymbolTable::_shared_table; volatile bool SymbolTable::_alt_hash = false; volatile bool SymbolTable::_lookup_shared_first = false; // Static arena for symbols that are not deallocated @@ -224,10 +244,20 @@ }; }; +class SharedSymbolIterator { + SymbolClosure* _symbol_closure; +public: + SharedSymbolIterator(SymbolClosure* f) : _symbol_closure(f) {} + void do_value(Symbol* symbol) { + _symbol_closure->do_symbol(&symbol); + } +}; + // Call function for all symbols in the symbol table. void SymbolTable::symbols_do(SymbolClosure *cl) { // all symbols from shared table - _shared_table.symbols_do(cl); + SharedSymbolIterator iter(cl); + _shared_table.iterate(&iter); // all symbols from the dynamic table SymbolsDo sd(cl); @@ -597,6 +627,22 @@ } #if INCLUDE_CDS +class CompactSymbolTableWriter: public CompactHashtableWriter { +public: + CompactSymbolTableWriter(int num_buckets, CompactHashtableStats* stats) : + CompactHashtableWriter(num_buckets, stats) {} + void add(unsigned int hash, Symbol *symbol) { + uintx deltax = MetaspaceShared::object_delta(symbol); + // When the symbols are stored into the archive, we already check that + // they won't be more than MAX_SHARED_DELTA from the base address, or + // else the dumping would have been aborted. + assert(deltax <= MAX_SHARED_DELTA, "must not be"); + u4 delta = u4(deltax); + + CompactHashtableWriter::add(hash, delta); + } +}; + struct CopyToArchive : StackObj { CompactSymbolTableWriter* _writer; CopyToArchive(CompactSymbolTableWriter* writer) : _writer(writer) {} @@ -613,7 +659,6 @@ // add to the compact table _writer->add(fixed_hash, sym); - return true; } }; @@ -631,7 +676,7 @@ CompactSymbolTableWriter writer(num_buckets > 1 ? num_buckets : 1, &MetaspaceShared::stats()->symbol); copy_shared_symbol_table(&writer); - writer.dump(&_shared_table); + writer.dump(&_shared_table, "symbol"); // Verify table is correct Symbol* sym = vmSymbols::java_lang_Object(); @@ -642,7 +687,6 @@ } void SymbolTable::serialize(SerializeClosure* soc) { - _shared_table.set_type(CompactHashtable::_symbol_table); _shared_table.serialize(soc); if (soc->writing()) {