mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 17:14:41 +02:00
8246181: Avoid walking SymbolTable during -Xshare:dump
All symbols at dump are created as permanent. Store them in a global array to avoid working SymbolTable. Reviewed-by: iklam, ccheung
This commit is contained in:
parent
1550fd889b
commit
0e60e8ad85
5 changed files with 47 additions and 42 deletions
|
@ -513,6 +513,13 @@ Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((sym == NULL) || sym->refcount() != 0, "found dead symbol");
|
assert((sym == NULL) || sym->refcount() != 0, "found dead symbol");
|
||||||
|
#if INCLUDE_CDS
|
||||||
|
if (DumpSharedSpaces) {
|
||||||
|
if (sym != NULL) {
|
||||||
|
MetaspaceShared::add_symbol(sym);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -663,6 +663,33 @@ class CollectClassesClosure : public KlassClosure {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Global object for holding symbols that created during class loading. See SymbolTable::new_symbol
|
||||||
|
static GrowableArray<Symbol*>* _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<Symbol*>(2048, mtSymbol);
|
||||||
|
}
|
||||||
|
_global_symbol_objects->append(sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
GrowableArray<Symbol*>* MetaspaceShared::collected_symbols() {
|
||||||
|
return _global_symbol_objects;
|
||||||
|
}
|
||||||
|
|
||||||
static void remove_unshareable_in_classes() {
|
static void remove_unshareable_in_classes() {
|
||||||
for (int i = 0; i < _global_klass_objects->length(); i++) {
|
for (int i = 0; i < _global_klass_objects->length(); i++) {
|
||||||
Klass* k = _global_klass_objects->at(i);
|
Klass* k = _global_klass_objects->at(i);
|
||||||
|
@ -1238,34 +1265,6 @@ public:
|
||||||
bool allow_nested_vm_operations() const { return true; }
|
bool allow_nested_vm_operations() const { return true; }
|
||||||
}; // class VM_PopulateDumpSharedSpace
|
}; // class VM_PopulateDumpSharedSpace
|
||||||
|
|
||||||
class SortedSymbolClosure: public SymbolClosure {
|
|
||||||
GrowableArray<Symbol*> _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<Symbol*>* get_sorted_symbols() {
|
|
||||||
return &_symbols;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ArchiveCompactor --
|
// ArchiveCompactor --
|
||||||
//
|
//
|
||||||
// This class is the central piece of shared archive compaction -- all metaspace data are
|
// This class is the central piece of shared archive compaction -- all metaspace data are
|
||||||
|
@ -1277,7 +1276,6 @@ class ArchiveCompactor : AllStatic {
|
||||||
static const int MAX_TABLE_SIZE = 1000000;
|
static const int MAX_TABLE_SIZE = 1000000;
|
||||||
|
|
||||||
static DumpAllocStats* _alloc_stats;
|
static DumpAllocStats* _alloc_stats;
|
||||||
static SortedSymbolClosure* _ssc;
|
|
||||||
|
|
||||||
typedef KVHashtable<address, address, mtInternal> RelocationTable;
|
typedef KVHashtable<address, address, mtInternal> RelocationTable;
|
||||||
static RelocationTable* _new_loc_table;
|
static RelocationTable* _new_loc_table;
|
||||||
|
@ -1421,8 +1419,6 @@ private:
|
||||||
public:
|
public:
|
||||||
static void copy_and_compact() {
|
static void copy_and_compact() {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
SortedSymbolClosure the_ssc; // StackObj
|
|
||||||
_ssc = &the_ssc;
|
|
||||||
|
|
||||||
log_info(cds)("Scanning all metaspace objects ... ");
|
log_info(cds)("Scanning all metaspace objects ... ");
|
||||||
{
|
{
|
||||||
|
@ -1458,9 +1454,11 @@ public:
|
||||||
{
|
{
|
||||||
log_info(cds)("Fixing symbol identity hash ... ");
|
log_info(cds)("Fixing symbol identity hash ... ");
|
||||||
os::init_random(0x12345678);
|
os::init_random(0x12345678);
|
||||||
GrowableArray<Symbol*>* symbols = _ssc->get_sorted_symbols();
|
GrowableArray<Symbol*>* all_symbols = MetaspaceShared::collected_symbols();
|
||||||
for (int i=0; i<symbols->length(); i++) {
|
all_symbols->sort(compare_symbols_by_address);
|
||||||
symbols->at(i)->update_identity_hash();
|
for (int i = 0; i < all_symbols->length(); i++) {
|
||||||
|
assert(all_symbols->at(i)->is_permanent(), "archived symbols must be permanent");
|
||||||
|
all_symbols->at(i)->update_identity_hash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
@ -1471,10 +1469,6 @@ public:
|
||||||
iterate_roots(&checker);
|
iterate_roots(&checker);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
_ssc = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We must relocate the System::_well_known_klasses only after we have copied the
|
// We must relocate the System::_well_known_klasses only after we have copied the
|
||||||
|
@ -1510,8 +1504,8 @@ public:
|
||||||
// (see Symbol::operator new(size_t, int)). So if we iterate the Symbols by
|
// (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
|
// ascending address order, we ensure that all Symbols are copied into deterministic
|
||||||
// locations in the archive.
|
// locations in the archive.
|
||||||
GrowableArray<Symbol*>* symbols = _ssc->get_sorted_symbols();
|
GrowableArray<Symbol*>* symbols = _global_symbol_objects;
|
||||||
for (int i=0; i<symbols->length(); i++) {
|
for (int i = 0; i < symbols->length(); i++) {
|
||||||
it->push(symbols->adr_at(i));
|
it->push(symbols->adr_at(i));
|
||||||
}
|
}
|
||||||
if (_global_klass_objects != NULL) {
|
if (_global_klass_objects != NULL) {
|
||||||
|
@ -1541,7 +1535,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
DumpAllocStats* ArchiveCompactor::_alloc_stats;
|
DumpAllocStats* ArchiveCompactor::_alloc_stats;
|
||||||
SortedSymbolClosure* ArchiveCompactor::_ssc;
|
|
||||||
ArchiveCompactor::RelocationTable* ArchiveCompactor::_new_loc_table;
|
ArchiveCompactor::RelocationTable* ArchiveCompactor::_new_loc_table;
|
||||||
|
|
||||||
void VM_PopulateDumpSharedSpace::dump_symbols() {
|
void VM_PopulateDumpSharedSpace::dump_symbols() {
|
||||||
|
|
|
@ -213,6 +213,8 @@ class MetaspaceShared : AllStatic {
|
||||||
TRAPS) NOT_CDS_RETURN_(0);
|
TRAPS) NOT_CDS_RETURN_(0);
|
||||||
|
|
||||||
static GrowableArray<Klass*>* collected_klasses();
|
static GrowableArray<Klass*>* collected_klasses();
|
||||||
|
static GrowableArray<Symbol*>* collected_symbols();
|
||||||
|
static void add_symbol(Symbol* sym) NOT_CDS_RETURN;
|
||||||
|
|
||||||
static ReservedSpace* shared_rs() {
|
static ReservedSpace* shared_rs() {
|
||||||
CDS_ONLY(return &_shared_rs);
|
CDS_ONLY(return &_shared_rs);
|
||||||
|
|
|
@ -151,6 +151,7 @@ Mutex* CDSClassFileStream_lock = NULL;
|
||||||
#endif
|
#endif
|
||||||
Mutex* DumpTimeTable_lock = NULL;
|
Mutex* DumpTimeTable_lock = NULL;
|
||||||
Mutex* CDSLambda_lock = NULL;
|
Mutex* CDSLambda_lock = NULL;
|
||||||
|
Mutex* CDSAddSymbol_lock = NULL;
|
||||||
#endif // INCLUDE_CDS
|
#endif // INCLUDE_CDS
|
||||||
|
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
|
@ -344,8 +345,9 @@ void mutex_init() {
|
||||||
#if INCLUDE_JVMTI
|
#if INCLUDE_JVMTI
|
||||||
def(CDSClassFileStream_lock , PaddedMutex , max_nonleaf, false, _safepoint_check_always);
|
def(CDSClassFileStream_lock , PaddedMutex , max_nonleaf, false, _safepoint_check_always);
|
||||||
#endif
|
#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(CDSLambda_lock , PaddedMutex , leaf, true, _safepoint_check_never);
|
||||||
|
def(CDSAddSymbol_lock , PaddedMutex , leaf - 1, true, _safepoint_check_never);
|
||||||
#endif // INCLUDE_CDS
|
#endif // INCLUDE_CDS
|
||||||
|
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
|
|
|
@ -130,6 +130,7 @@ extern Mutex* CDSClassFileStream_lock; // FileMapInfo::open_stream_for
|
||||||
#endif
|
#endif
|
||||||
extern Mutex* DumpTimeTable_lock; // SystemDictionaryShared::find_or_allocate_info_for
|
extern Mutex* DumpTimeTable_lock; // SystemDictionaryShared::find_or_allocate_info_for
|
||||||
extern Mutex* CDSLambda_lock; // SystemDictionaryShared::get_shared_lambda_proxy_class
|
extern Mutex* CDSLambda_lock; // SystemDictionaryShared::get_shared_lambda_proxy_class
|
||||||
|
extern Mutex* CDSAddSymbol_lock; // SystemDictionaryShared::add_symbol
|
||||||
#endif // INCLUDE_CDS
|
#endif // INCLUDE_CDS
|
||||||
#if INCLUDE_JFR
|
#if INCLUDE_JFR
|
||||||
extern Mutex* JfrStacktrace_lock; // used to guard access to the JFR stacktrace table
|
extern Mutex* JfrStacktrace_lock; // used to guard access to the JFR stacktrace table
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue