--- old/src/hotspot/share/classfile/symbolTable.cpp 2020-06-23 13:51:54.636118254 -0700 +++ new/src/hotspot/share/classfile/symbolTable.cpp 2020-06-23 13:51:54.324106509 -0700 @@ -513,6 +513,13 @@ } assert((sym == NULL) || sym->refcount() != 0, "found dead symbol"); +#if INCLUDE_CDS + if (DumpSharedSpaces) { + if (sym != NULL) { + MetaspaceShared::add_symbol(sym); + } + } +#endif return sym; } --- old/src/hotspot/share/memory/metaspaceShared.cpp 2020-06-23 13:51:55.212139936 -0700 +++ new/src/hotspot/share/memory/metaspaceShared.cpp 2020-06-23 13:51:54.892127890 -0700 @@ -663,6 +663,33 @@ } }; +// Global object for holding symbols that created during class loading. See SymbolTable::new_symbol +static GrowableArray* _global_symbol_objects = NULL; + +static int compare_symbols_by_address(Symbol** a, Symbol** b) { + if (a[0] < b[0]) { + return -1; + } else if (a[0] == b[0]) { + ResourceMark rm; + log_warning(cds)("Duplicated symbol %s unexpected", (*a)->as_C_string()); + return 0; + } else { + return 1; + } +} + +void MetaspaceShared::add_symbol(Symbol* sym) { + MutexLocker ml(CDSAddSymbol_lock, Mutex::_no_safepoint_check_flag); + if (_global_symbol_objects == NULL) { + _global_symbol_objects = new (ResourceObj::C_HEAP, mtSymbol) GrowableArray(2048, mtSymbol); + } + _global_symbol_objects->append(sym); +} + +GrowableArray* MetaspaceShared::collected_symbols() { + return _global_symbol_objects; +} + static void remove_unshareable_in_classes() { for (int i = 0; i < _global_klass_objects->length(); i++) { Klass* k = _global_klass_objects->at(i); @@ -1238,34 +1265,6 @@ bool allow_nested_vm_operations() const { return true; } }; // class VM_PopulateDumpSharedSpace -class SortedSymbolClosure: public SymbolClosure { - GrowableArray _symbols; - virtual void do_symbol(Symbol** sym) { - assert((*sym)->is_permanent(), "archived symbols must be permanent"); - _symbols.append(*sym); - } - static int compare_symbols_by_address(Symbol** a, Symbol** b) { - if (a[0] < b[0]) { - return -1; - } else if (a[0] == b[0]) { - ResourceMark rm; - log_warning(cds)("Duplicated symbol %s unexpected", (*a)->as_C_string()); - return 0; - } else { - return 1; - } - } - -public: - SortedSymbolClosure() { - SymbolTable::symbols_do(this); - _symbols.sort(compare_symbols_by_address); - } - GrowableArray* get_sorted_symbols() { - return &_symbols; - } -}; - // ArchiveCompactor -- // // This class is the central piece of shared archive compaction -- all metaspace data are @@ -1277,7 +1276,6 @@ static const int MAX_TABLE_SIZE = 1000000; static DumpAllocStats* _alloc_stats; - static SortedSymbolClosure* _ssc; typedef KVHashtable RelocationTable; static RelocationTable* _new_loc_table; @@ -1421,8 +1419,6 @@ public: static void copy_and_compact() { ResourceMark rm; - SortedSymbolClosure the_ssc; // StackObj - _ssc = &the_ssc; log_info(cds)("Scanning all metaspace objects ... "); { @@ -1458,9 +1454,10 @@ { log_info(cds)("Fixing symbol identity hash ... "); os::init_random(0x12345678); - GrowableArray* symbols = _ssc->get_sorted_symbols(); - for (int i=0; ilength(); i++) { - symbols->at(i)->update_identity_hash(); + GrowableArray* all_symbols = MetaspaceShared::collected_symbols(); + all_symbols->sort(compare_symbols_by_address); + for (int i = 0; i < all_symbols->length(); i++) { + all_symbols->at(i)->update_identity_hash(); } } #ifdef ASSERT @@ -1471,10 +1468,6 @@ iterate_roots(&checker); } #endif - - - // cleanup - _ssc = NULL; } // We must relocate the System::_well_known_klasses only after we have copied the @@ -1510,8 +1503,8 @@ // (see Symbol::operator new(size_t, int)). So if we iterate the Symbols by // ascending address order, we ensure that all Symbols are copied into deterministic // locations in the archive. - GrowableArray* symbols = _ssc->get_sorted_symbols(); - for (int i=0; ilength(); i++) { + GrowableArray* symbols = _global_symbol_objects; + for (int i = 0; i < symbols->length(); i++) { it->push(symbols->adr_at(i)); } if (_global_klass_objects != NULL) { @@ -1541,7 +1534,6 @@ }; DumpAllocStats* ArchiveCompactor::_alloc_stats; -SortedSymbolClosure* ArchiveCompactor::_ssc; ArchiveCompactor::RelocationTable* ArchiveCompactor::_new_loc_table; void VM_PopulateDumpSharedSpace::dump_symbols() { --- old/src/hotspot/share/memory/metaspaceShared.hpp 2020-06-23 13:51:55.788161618 -0700 +++ new/src/hotspot/share/memory/metaspaceShared.hpp 2020-06-23 13:51:55.472149723 -0700 @@ -213,6 +213,8 @@ TRAPS) NOT_CDS_RETURN_(0); static GrowableArray* collected_klasses(); + static GrowableArray* collected_symbols(); + static void add_symbol(Symbol* sym) NOT_CDS_RETURN; static ReservedSpace* shared_rs() { CDS_ONLY(return &_shared_rs); --- old/src/hotspot/share/runtime/mutexLocker.cpp 2020-06-23 13:51:56.356183000 -0700 +++ new/src/hotspot/share/runtime/mutexLocker.cpp 2020-06-23 13:51:56.040171105 -0700 @@ -151,6 +151,7 @@ #endif Mutex* DumpTimeTable_lock = NULL; Mutex* CDSLambda_lock = NULL; +Mutex* CDSAddSymbol_lock = NULL; #endif // INCLUDE_CDS #if INCLUDE_JVMCI @@ -344,8 +345,9 @@ #if INCLUDE_JVMTI def(CDSClassFileStream_lock , PaddedMutex , max_nonleaf, false, _safepoint_check_always); #endif - def(DumpTimeTable_lock , PaddedMutex , leaf - 1, true, _safepoint_check_never); + def(DumpTimeTable_lock , PaddedMutex , leaf - 1, true, _safepoint_check_never); def(CDSLambda_lock , PaddedMutex , leaf, true, _safepoint_check_never); + def(CDSAddSymbol_lock , PaddedMutex , leaf - 1, true, _safepoint_check_never); #endif // INCLUDE_CDS #if INCLUDE_JVMCI --- old/src/hotspot/share/runtime/mutexLocker.hpp 2020-06-23 13:51:56.920204231 -0700 +++ new/src/hotspot/share/runtime/mutexLocker.hpp 2020-06-23 13:51:56.604192335 -0700 @@ -130,6 +130,7 @@ #endif extern Mutex* DumpTimeTable_lock; // SystemDictionaryShared::find_or_allocate_info_for extern Mutex* CDSLambda_lock; // SystemDictionaryShared::get_shared_lambda_proxy_class +extern Mutex* CDSAddSymbol_lock; // SystemDictionaryShared::add_symbol #endif // INCLUDE_CDS #if INCLUDE_JFR extern Mutex* JfrStacktrace_lock; // used to guard access to the JFR stacktrace table