--- old/src/hotspot/share/classfile/compactHashtable.cpp 2018-09-18 21:27:52.965198061 -0700 +++ new/src/hotspot/share/classfile/compactHashtable.cpp 2018-09-18 21:27:52.709188200 -0700 @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "jvm.h" -#include "classfile/compactHashtable.inline.hpp" +#include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "logging/logMessage.hpp" #include "memory/heapShared.inline.hpp" @@ -170,33 +170,6 @@ ///////////////////////////////////////////////////////////// // -// Customization for dumping Symbol and String tables - -void CompactSymbolTableWriter::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); -} - -void CompactStringTableWriter::add(unsigned int hash, oop string) { - CompactHashtableWriter::add(hash, CompressedOops::encode(string)); -} - -void CompactSymbolTableWriter::dump(CompactHashtable *cht) { - CompactHashtableWriter::dump(cht, "symbol"); -} - -void CompactStringTableWriter::dump(CompactHashtable *cht) { - CompactHashtableWriter::dump(cht, "string"); -} - -///////////////////////////////////////////////////////////// -// // The CompactHashtable implementation // @@ -208,95 +181,6 @@ soc->do_ptr((void**)&_entries); } -bool SimpleCompactHashtable::exists(u4 value) { - assert(!DumpSharedSpaces, "run-time only"); - - if (_entry_count == 0) { - return false; - } - - unsigned int hash = (unsigned int)value; - int index = hash % _bucket_count; - u4 bucket_info = _buckets[index]; - u4 bucket_offset = BUCKET_OFFSET(bucket_info); - int bucket_type = BUCKET_TYPE(bucket_info); - u4* entry = _entries + bucket_offset; - - if (bucket_type == VALUE_ONLY_BUCKET_TYPE) { - return (entry[0] == value); - } else { - u4*entry_max = _entries + BUCKET_OFFSET(_buckets[index + 1]); - while (entry -inline void SimpleCompactHashtable::iterate(const I& iterator) { - for (u4 i = 0; i < _bucket_count; i++) { - u4 bucket_info = _buckets[i]; - u4 bucket_offset = BUCKET_OFFSET(bucket_info); - int bucket_type = BUCKET_TYPE(bucket_info); - u4* entry = _entries + bucket_offset; - - if (bucket_type == VALUE_ONLY_BUCKET_TYPE) { - iterator.do_value(_base_address, entry[0]); - } else { - u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]); - while (entry < entry_max) { - iterator.do_value(_base_address, entry[1]); - entry += 2; - } - } - } -} - -template void CompactHashtable::serialize(SerializeClosure* soc) { - SimpleCompactHashtable::serialize(soc); - soc->do_u4(&_type); -} - -class CompactHashtable_SymbolIterator { - SymbolClosure* const _closure; -public: - CompactHashtable_SymbolIterator(SymbolClosure *cl) : _closure(cl) {} - inline void do_value(address base_address, u4 offset) const { - Symbol* sym = (Symbol*)((void*)(base_address + offset)); - _closure->do_symbol(&sym); - } -}; - -template void CompactHashtable::symbols_do(SymbolClosure *cl) { - CompactHashtable_SymbolIterator iterator(cl); - iterate(iterator); -} - -class CompactHashtable_OopIterator { - OopClosure* const _closure; -public: - CompactHashtable_OopIterator(OopClosure *cl) : _closure(cl) {} - inline void do_value(address base_address, u4 offset) const { - narrowOop v = (narrowOop)offset; - oop obj = HeapShared::decode_from_archive(v); - _closure->do_oop(&obj); - } -}; - -template void CompactHashtable::oops_do(OopClosure* cl) { - assert(_type == _string_table || _bucket_count == 0, "sanity"); - CompactHashtable_OopIterator iterator(cl); - iterate(iterator); -} - -// Explicitly instantiate these types -template class CompactHashtable; -template class CompactHashtable; - #ifndef O_BINARY // if defined (Win32) use binary files. #define O_BINARY 0 // otherwise do nothing. #endif --- old/src/hotspot/share/classfile/compactHashtable.hpp 2018-09-18 21:27:53.477217783 -0700 +++ new/src/hotspot/share/classfile/compactHashtable.hpp 2018-09-18 21:27:53.217207768 -0700 @@ -29,7 +29,14 @@ #include "oops/symbol.hpp" #include "utilities/hashtable.hpp" -template class CompactHashtable; + +template < + typename K, + typename V, + V (*DECODE)(address base_address, u4 offset), + bool (*EQUALS)(V value, K key, int len) + > +class CompactHashtable; class NumberSeq; class SimpleCompactHashtable; class SerializeClosure; @@ -108,9 +115,6 @@ ~CompactHashtableWriter(); void add(unsigned int hash, u4 value); - void add(u4 value) { - add((unsigned int)value, value); - } private: void allocate_table(); @@ -118,23 +122,6 @@ public: void dump(SimpleCompactHashtable *cht, const char* table_name); - const char* table_name(); -}; - -class CompactSymbolTableWriter: public CompactHashtableWriter { -public: - CompactSymbolTableWriter(int num_buckets, CompactHashtableStats* stats) : - CompactHashtableWriter(num_buckets, stats) {} - void add(unsigned int hash, Symbol *symbol); - void dump(CompactHashtable *cht); -}; - -class CompactStringTableWriter: public CompactHashtableWriter { -public: - CompactStringTableWriter(int num_entries, CompactHashtableStats* stats) : - CompactHashtableWriter(num_entries, stats) {} - void add(unsigned int hash, oop string); - void dump(CompactHashtable *cht); }; #define REGULAR_BUCKET_TYPE 0 @@ -148,8 +135,7 @@ ///////////////////////////////////////////////////////////////////////////// // -// CompactHashtable is used to stored the CDS archive's symbol/string table. Used -// at runtime only to access the compact table from the archive. +// CompactHashtable is used to store the CDS archive's symbol/string tables. // // Because these tables are read-only (no entries can be added/deleted) at run-time // and tend to have large number of entries, we try to minimize the footprint @@ -225,10 +211,6 @@ _entries = entries; } - template inline void iterate(const I& iterator); - - bool exists(u4 value); - // For reading from/writing to the CDS archive void serialize(SerializeClosure* soc); @@ -237,44 +219,74 @@ } }; -template class CompactHashtable : public SimpleCompactHashtable { +template < + typename K, + typename V, + V (*DECODE)(address base_address, u4 offset), + bool (*EQUALS)(V value, K key, int len) + > +class CompactHashtable : public SimpleCompactHashtable { friend class VMStructs; -public: - enum CompactHashtableType { - _symbol_table = 0, - _string_table = 1 - }; - -private: - u4 _type; - - inline Symbol* decode_entry(CompactHashtable* const t, - u4 offset, const char* name, int len); + V decode(u4 offset) const { + return DECODE(_base_address, offset); + } - inline oop decode_entry(CompactHashtable* const t, - u4 offset, const char* name, int len); public: CompactHashtable() : SimpleCompactHashtable() {} - void set_type(CompactHashtableType type) { - _type = (u4)type; + // Lookup a value V from the compact table using key K + inline V lookup(K key, unsigned int hash, int len) const { + if (_entry_count > 0) { + int index = hash % _bucket_count; + u4 bucket_info = _buckets[index]; + u4 bucket_offset = BUCKET_OFFSET(bucket_info); + int bucket_type = BUCKET_TYPE(bucket_info); + u4* entry = _entries + bucket_offset; + + if (bucket_type == VALUE_ONLY_BUCKET_TYPE) { + V value = decode(entry[0]); + if (EQUALS(value, key, len)) { + return value; + } + } else { + // This is a regular bucket, which has more than one + // entries. Each entry is a pair of entry (hash, offset). + // Seek until the end of the bucket. + u4* entry_max = _entries + BUCKET_OFFSET(_buckets[index + 1]); + while (entry < entry_max) { + unsigned int h = (unsigned int)(entry[0]); + if (h == hash) { + V value = decode(entry[1]); + if (EQUALS(value, key, len)) { + return value; + } + } + entry += 2; + } + } + } + return NULL; } - // Lookup an entry from the compact table - inline T lookup(const N* name, unsigned int hash, int len); - - // iterate over symbols - void symbols_do(SymbolClosure *cl); - - // iterate over strings - void oops_do(OopClosure* f); - - // For reading from/writing to the CDS archive - void serialize(SerializeClosure* soc); - - uintx base_address() { - return (uintx) _base_address; + template + inline void iterate(ITER* iter) const { + for (u4 i = 0; i < _bucket_count; i++) { + u4 bucket_info = _buckets[i]; + u4 bucket_offset = BUCKET_OFFSET(bucket_info); + int bucket_type = BUCKET_TYPE(bucket_info); + u4* entry = _entries + bucket_offset; + + if (bucket_type == VALUE_ONLY_BUCKET_TYPE) { + iter->do_value(decode(entry[0])); + } else { + u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]); + while (entry < entry_max) { + iter->do_value(decode(entry[1])); + entry += 2; + } + } + } } }; --- old/src/hotspot/share/classfile/javaClasses.cpp 2018-09-18 21:27:53.993237659 -0700 +++ new/src/hotspot/share/classfile/javaClasses.cpp 2018-09-18 21:27:53.733227644 -0700 @@ -260,7 +260,7 @@ return h_obj; } -Handle java_lang_String::create_from_unicode(jchar* unicode, int length, TRAPS) { +Handle java_lang_String::create_from_unicode(const jchar* unicode, int length, TRAPS) { bool is_latin1 = CompactStrings && UNICODE::is_latin1(unicode, length); Handle h_obj = basic_create(length, is_latin1, CHECK_NH); typeArrayOop buffer = value(h_obj()); @@ -290,7 +290,7 @@ return h_obj; } -oop java_lang_String::create_oop_from_unicode(jchar* unicode, int length, TRAPS) { +oop java_lang_String::create_oop_from_unicode(const jchar* unicode, int length, TRAPS) { Handle h_obj = create_from_unicode(unicode, length, CHECK_0); return h_obj(); } @@ -662,7 +662,7 @@ } } -bool java_lang_String::equals(oop java_string, jchar* chars, int len) { +bool java_lang_String::equals(oop java_string, const jchar* chars, int len) { assert(java_string->klass() == SystemDictionary::String_klass(), "must be java_string"); typeArrayOop value = java_lang_String::value_no_keepalive(java_string); @@ -2588,7 +2588,7 @@ // Fill in class name ResourceMark rm(THREAD); const char* str = holder->external_name(); - oop classname = StringTable::intern((char*) str, CHECK); + oop classname = StringTable::intern(str, CHECK); java_lang_StackTraceElement::set_declaringClass(element(), classname); java_lang_StackTraceElement::set_declaringClassObject(element(), holder->java_mirror()); --- old/src/hotspot/share/classfile/javaClasses.hpp 2018-09-18 21:27:54.545258922 -0700 +++ new/src/hotspot/share/classfile/javaClasses.hpp 2018-09-18 21:27:54.285248907 -0700 @@ -114,8 +114,8 @@ static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; // Instance creation - static Handle create_from_unicode(jchar* unicode, int len, TRAPS); - static oop create_oop_from_unicode(jchar* unicode, int len, TRAPS); + static Handle create_from_unicode(const jchar* unicode, int len, TRAPS); + static oop create_oop_from_unicode(const jchar* unicode, int len, TRAPS); static Handle create_from_str(const char* utf8_str, TRAPS); static oop create_oop_from_str(const char* utf8_str, TRAPS); static Handle create_from_symbol(Symbol* symbol, TRAPS); @@ -189,7 +189,7 @@ static unsigned int hash_code(oop java_string); - static bool equals(oop java_string, jchar* chars, int len); + static bool equals(oop java_string, const jchar* chars, int len); static bool equals(oop str1, oop str2); // Conversion between '.' and '/' formats --- old/src/hotspot/share/classfile/stringTable.cpp 2018-09-18 21:27:55.057278644 -0700 +++ new/src/hotspot/share/classfile/stringTable.cpp 2018-09-18 21:27:54.801268783 -0700 @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" -#include "classfile/compactHashtable.inline.hpp" +#include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" @@ -35,6 +35,7 @@ #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" +#include "memory/heapShared.inline.hpp" #include "memory/metaspaceShared.inline.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" @@ -62,9 +63,22 @@ // If we have as many dead items as 50% of the number of bucket #define CLEAN_DEAD_HIGH_WATER_MARK 0.5 +#if INCLUDE_CDS_JAVA_HEAP +inline oop read_string_from_compact_hashtable(address base_address, u4 offset) { + assert(sizeof(narrowOop) == sizeof(offset), "must be"); + narrowOop v = (narrowOop)offset; + return HeapShared::decode_from_archive(v); +} + +static CompactHashtable< + const jchar*, oop, + read_string_from_compact_hashtable, + java_lang_String::equals +> _shared_table; +#endif + // -------------------------------------------------------------------------- StringTable* StringTable::_the_table = NULL; -CompactHashtable StringTable::_shared_table; volatile bool StringTable::_shared_string_mapped = false; volatile bool StringTable::_alt_hash = false; @@ -134,7 +148,7 @@ *is_dead = true; return false; } - bool equals = java_lang_String::equals(val_oop, (jchar*)_str, _len); + bool equals = java_lang_String::equals(val_oop, _str, _len); if (!equals) { return false; } @@ -236,7 +250,7 @@ return lookup(chars, length); } -oop StringTable::lookup(jchar* name, int len) { +oop StringTable::lookup(const jchar* name, int len) { unsigned int hash = java_lang_String::hash_code(name, len); oop string = StringTable::the_table()->lookup_shared(name, len, hash); if (string != NULL) { @@ -263,7 +277,7 @@ } }; -oop StringTable::do_lookup(jchar* name, int len, uintx hash) { +oop StringTable::do_lookup(const jchar* name, int len, uintx hash) { Thread* thread = Thread::current(); StringTableLookupJchar lookup(thread, hash, name, len); StringTableGet stg(thread); @@ -308,7 +322,7 @@ return result; } -oop StringTable::intern(Handle string_or_null_h, jchar* name, int len, TRAPS) { +oop StringTable::intern(Handle string_or_null_h, const jchar* name, int len, TRAPS) { // shared table always uses java_lang_String::hash_code unsigned int hash = java_lang_String::hash_code(name, len); oop found_string = StringTable::the_table()->lookup_shared(name, len, hash); @@ -346,7 +360,7 @@ } }; -oop StringTable::do_intern(Handle string_or_null_h, jchar* name, +oop StringTable::do_intern(Handle string_or_null_h, const jchar* name, int len, uintx hash, TRAPS) { HandleMark hm(THREAD); // cleanup strings created Handle string_h; @@ -775,10 +789,10 @@ // Sharing #if INCLUDE_CDS_JAVA_HEAP -oop StringTable::lookup_shared(jchar* name, int len, unsigned int hash) { +oop StringTable::lookup_shared(const jchar* name, int len, unsigned int hash) { assert(hash == java_lang_String::hash_code(name, len), "hash must be computed using java_lang_String::hash_code"); - return _shared_table.lookup((const char*)name, hash, len); + return _shared_table.lookup(name, hash, len); } oop StringTable::create_archived_string(oop s, Thread* THREAD) { @@ -805,6 +819,15 @@ return new_s; } +class CompactStringTableWriter: public CompactHashtableWriter { +public: + CompactStringTableWriter(int num_entries, CompactHashtableStats* stats) : + CompactHashtableWriter(num_entries, stats) {} + void add(unsigned int hash, oop string) { + CompactHashtableWriter::add(hash, CompressedOops::encode(string)); + } +}; + struct CopyToArchive : StackObj { CompactStringTableWriter* _writer; CopyToArchive(CompactStringTableWriter* writer) : _writer(writer) {} @@ -849,11 +872,10 @@ // Copy the interned strings into the "string space" within the java heap copy_shared_string_table(&writer); - writer.dump(&_shared_table); + writer.dump(&_shared_table, "string"); } void StringTable::serialize(SerializeClosure* soc) { - _shared_table.set_type(CompactHashtable::_string_table); _shared_table.serialize(soc); if (soc->writing()) { @@ -864,7 +886,17 @@ } } +class SharedStringIterator { + OopClosure* _oop_closure; +public: + SharedStringIterator(OopClosure* f) : _oop_closure(f) {} + void do_value(oop string) { + _oop_closure->do_oop(&string); + } +}; + void StringTable::shared_oops_do(OopClosure* f) { - _shared_table.oops_do(f); + SharedStringIterator iter(f); + _shared_table.iterate(&iter); } #endif //INCLUDE_CDS_JAVA_HEAP --- old/src/hotspot/share/classfile/stringTable.hpp 2018-09-18 21:27:55.573298521 -0700 +++ new/src/hotspot/share/classfile/stringTable.hpp 2018-09-18 21:27:55.321288813 -0700 @@ -33,7 +33,6 @@ #include "oops/weakHandle.hpp" #include "utilities/concurrentHashTable.hpp" -template class CompactHashtable; class CompactStringTableWriter; class SerializeClosure; @@ -56,8 +55,6 @@ // The string table static StringTable* _the_table; - // Shared string table - static CompactHashtable _shared_table; static volatile bool _shared_string_mapped; static volatile bool _alt_hash; @@ -88,9 +85,9 @@ StringTable(); - static oop intern(Handle string_or_null_h, jchar* name, int len, TRAPS); - oop do_intern(Handle string_or_null, jchar* name, int len, uintx hash, TRAPS); - oop do_lookup(jchar* name, int len, uintx hash); + static oop intern(Handle string_or_null_h, const jchar* name, int len, TRAPS); + oop do_intern(Handle string_or_null, const jchar* name, int len, uintx hash, TRAPS); + oop do_lookup(const jchar* name, int len, uintx hash); void concurrent_work(JavaThread* jt); void print_table_statistics(outputStream* st, const char* table_name); @@ -151,7 +148,7 @@ // Probing static oop lookup(Symbol* symbol); - static oop lookup(jchar* chars, int length); + static oop lookup(const jchar* chars, int length); // Interning static oop intern(Symbol* symbol, TRAPS); @@ -165,7 +162,7 @@ // Sharing private: - oop lookup_shared(jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL); + oop lookup_shared(const jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL); static void copy_shared_string_table(CompactStringTableWriter* ch_table) NOT_CDS_JAVA_HEAP_RETURN; public: static oop create_archived_string(oop s, Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN_(NULL); --- 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()) { --- old/src/hotspot/share/classfile/symbolTable.hpp 2018-09-18 21:27:56.813346285 -0700 +++ new/src/hotspot/share/classfile/symbolTable.hpp 2018-09-18 21:27:56.545335962 -0700 @@ -84,7 +84,6 @@ operator Symbol*() { return _temp; } }; -template class CompactHashtable; class CompactSymbolTableWriter; class SerializeClosure; @@ -108,8 +107,6 @@ // The symbol table static SymbolTable* _the_table; - // Shared symbol table. - static CompactHashtable _shared_table; static volatile bool _lookup_shared_first; static volatile bool _alt_hash; --- old/src/hotspot/share/classfile/systemDictionaryShared.cpp 2018-09-18 21:27:57.437370321 -0700 +++ new/src/hotspot/share/classfile/systemDictionaryShared.cpp 2018-09-18 21:27:57.177360306 -0700 @@ -28,7 +28,6 @@ #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderExt.hpp" -#include "classfile/compactHashtable.inline.hpp" #include "classfile/dictionary.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" --- old/src/hotspot/share/memory/filemap.cpp 2018-09-18 21:27:58.101395898 -0700 +++ new/src/hotspot/share/memory/filemap.cpp 2018-09-18 21:27:57.833385575 -0700 @@ -26,7 +26,6 @@ #include "jvm.h" #include "classfile/classLoader.inline.hpp" #include "classfile/classLoaderExt.hpp" -#include "classfile/compactHashtable.inline.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionaryShared.hpp" --- old/src/hotspot/share/services/diagnosticCommand.cpp 2018-09-18 21:27:58.769421629 -0700 +++ new/src/hotspot/share/services/diagnosticCommand.cpp 2018-09-18 21:27:58.501411306 -0700 @@ -26,7 +26,6 @@ #include "jvm.h" #include "classfile/classLoaderHierarchyDCmd.hpp" #include "classfile/classLoaderStats.hpp" -#include "classfile/compactHashtable.hpp" #include "compiler/compileBroker.hpp" #include "compiler/directivesParser.hpp" #include "gc/shared/vmGCOperations.hpp" --- old/src/hotspot/share/utilities/utf8.cpp 2018-09-18 21:27:59.349443971 -0700 +++ new/src/hotspot/share/utilities/utf8.cpp 2018-09-18 21:27:59.089433955 -0700 @@ -401,7 +401,7 @@ return (c <= 0x00FF); } -bool UNICODE::is_latin1(jchar* base, int length) { +bool UNICODE::is_latin1(const jchar* base, int length) { for (int index = 0; index < length; index++) { if (base[index] > 0x00FF) { return false; @@ -434,7 +434,7 @@ } template -int UNICODE::utf8_length(T* base, int length) { +int UNICODE::utf8_length(const T* base, int length) { int result = 0; for (int index = 0; index < length; index++) { T c = base[index]; @@ -444,7 +444,7 @@ } template -char* UNICODE::as_utf8(T* base, int& length) { +char* UNICODE::as_utf8(const T* base, int& length) { int utf8_len = utf8_length(base, length); u_char* buf = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1); char* result = as_utf8(base, length, (char*) buf, utf8_len + 1); @@ -454,7 +454,7 @@ return (char*) result; } -char* UNICODE::as_utf8(jchar* base, int length, char* buf, int buflen) { +char* UNICODE::as_utf8(const jchar* base, int length, char* buf, int buflen) { u_char* p = (u_char*)buf; for (int index = 0; index < length; index++) { jchar c = base[index]; @@ -466,7 +466,7 @@ return buf; } -char* UNICODE::as_utf8(jbyte* base, int length, char* buf, int buflen) { +char* UNICODE::as_utf8(const jbyte* base, int length, char* buf, int buflen) { u_char* p = (u_char*)buf; u_char* end = (u_char*)buf + buflen; for (int index = 0; index < length; index++) { @@ -496,7 +496,7 @@ // returns the quoted ascii length of a unicode string template -int UNICODE::quoted_ascii_length(T* base, int length) { +int UNICODE::quoted_ascii_length(const T* base, int length) { int result = 0; for (int i = 0; i < length; i++) { T c = base[i]; @@ -529,11 +529,11 @@ } // Explicit instantiation for all supported types. -template int UNICODE::utf8_length(jbyte* base, int length); -template int UNICODE::utf8_length(jchar* base, int length); -template char* UNICODE::as_utf8(jbyte* base, int& length); -template char* UNICODE::as_utf8(jchar* base, int& length); -template int UNICODE::quoted_ascii_length(jbyte* base, int length); -template int UNICODE::quoted_ascii_length(jchar* base, int length); +template int UNICODE::utf8_length(const jbyte* base, int length); +template int UNICODE::utf8_length(const jchar* base, int length); +template char* UNICODE::as_utf8(const jbyte* base, int& length); +template char* UNICODE::as_utf8(const jchar* base, int& length); +template int UNICODE::quoted_ascii_length(const jbyte* base, int length); +template int UNICODE::quoted_ascii_length(const jchar* base, int length); template void UNICODE::as_quoted_ascii(const jbyte* base, int length, char* buf, int buflen); template void UNICODE::as_quoted_ascii(const jchar* base, int length, char* buf, int buflen); --- old/src/hotspot/share/utilities/utf8.hpp 2018-09-18 21:27:59.853463385 -0700 +++ new/src/hotspot/share/utilities/utf8.hpp 2018-09-18 21:27:59.597453523 -0700 @@ -90,14 +90,14 @@ static bool is_latin1(jchar c); // checks if the given string can be encoded as latin1 - static bool is_latin1(jchar* base, int length); + static bool is_latin1(const jchar* base, int length); // returns the utf8 size of a unicode character static int utf8_size(jchar c); static int utf8_size(jbyte c); // returns the utf8 length of a unicode string - template static int utf8_length(T* base, int length); + template static int utf8_length(const T* base, int length); // converts a unicode string to utf8 string static void convert_to_utf8(const jchar* base, int length, char* utf8_buffer); @@ -105,12 +105,12 @@ // converts a unicode string to a utf8 string; result is allocated // in resource area unless a buffer is provided. The unicode 'length' // parameter is set to the length of the result utf8 string. - template static char* as_utf8(T* base, int& length); - static char* as_utf8(jchar* base, int length, char* buf, int buflen); - static char* as_utf8(jbyte* base, int length, char* buf, int buflen); + template static char* as_utf8(const T* base, int& length); + static char* as_utf8(const jchar* base, int length, char* buf, int buflen); + static char* as_utf8(const jbyte* base, int length, char* buf, int buflen); // returns the quoted ascii length of a unicode string - template static int quoted_ascii_length(T* base, int length); + template static int quoted_ascii_length(const T* base, int length); // converts a unicode string to quoted ascii template static void as_quoted_ascii(const T* base, int length, char* buf, int buflen); --- old/src/hotspot/share/classfile/compactHashtable.inline.hpp 2018-09-18 21:28:00.433485725 -0700 +++ /dev/null 2018-08-14 18:25:04.628316445 -0700 @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_CLASSFILE_COMPACTHASHTABLE_INLINE_HPP -#define SHARE_VM_CLASSFILE_COMPACTHASHTABLE_INLINE_HPP - -#include "classfile/compactHashtable.hpp" -#include "classfile/javaClasses.hpp" -#include "memory/allocation.inline.hpp" -#include "memory/filemap.hpp" -#include "memory/heapShared.inline.hpp" -#include "oops/oop.hpp" - -template -inline Symbol* CompactHashtable::decode_entry(CompactHashtable* const t, - u4 offset, const char* name, int len) { - Symbol* sym = (Symbol*)(_base_address + offset); - if (sym->equals(name, len)) { - assert(sym->refcount() == PERM_REFCOUNT, "must be shared"); - return sym; - } - - return NULL; -} - -template -inline oop CompactHashtable::decode_entry(CompactHashtable* const t, - u4 offset, const char* name, int len) { - narrowOop v = (narrowOop)offset; - oop string = HeapShared::decode_from_archive(v); - if (java_lang_String::equals(string, (jchar*)name, len)) { - return string; - } - - return NULL; -} - -template -inline T CompactHashtable::lookup(const N* name, unsigned int hash, int len) { - if (_entry_count > 0) { - int index = hash % _bucket_count; - u4 bucket_info = _buckets[index]; - u4 bucket_offset = BUCKET_OFFSET(bucket_info); - int bucket_type = BUCKET_TYPE(bucket_info); - u4* entry = _entries + bucket_offset; - - if (bucket_type == VALUE_ONLY_BUCKET_TYPE) { - T res = decode_entry(this, entry[0], name, len); - if (res != NULL) { - return res; - } - } else { - // This is a regular bucket, which has more than one - // entries. Each entry is a pair of entry (hash, offset). - // Seek until the end of the bucket. - u4* entry_max = _entries + BUCKET_OFFSET(_buckets[index + 1]); - while (entry < entry_max) { - unsigned int h = (unsigned int)(entry[0]); - if (h == hash) { - T res = decode_entry(this, entry[1], name, len); - if (res != NULL) { - return res; - } - } - entry += 2; - } - } - } - return NULL; -} - -#endif // SHARE_VM_CLASSFILE_COMPACTHASHTABLE_INLINE_HPP