Skip to content

Commit ce55336

Browse files
committed
8384416: Crash in RunTimeClassInfo::klass() during AOT cache assembly
Reviewed-by: kvn, heidinga, coleenp
1 parent ff81bd7 commit ce55336

6 files changed

Lines changed: 54 additions & 31 deletions

File tree

src/hotspot/share/cds/cdsConfig.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@ void CDSConfig::ergo_initialize() {
110110
AOTMapLogger::ergo_initialize();
111111

112112
setup_compiler_args();
113+
114+
if (is_dumping_full_module_graph()) {
115+
precond(allow_only_single_java_thread());
116+
117+
// The AttachListenerThread may execute Java code or load new classes. It might see
118+
// unexpected results after HeapShared::prepare_for_archiving().
119+
//
120+
// We disable all new incoming attach requests, so you can't use jcmd, etc, on this JVM.
121+
// Since we are not running any application code in this JVM and only executed a very
122+
// limited set of Java code (for module system init, class loading, indy resolution,
123+
// etc), there is usually no need to attach to this JVM.
124+
FLAG_SET_ERGO(DisableAttachMechanism, true);
125+
}
113126
}
114127

115128
const char* CDSConfig::default_archive_path() {

src/hotspot/share/cds/lambdaProxyClassDictionary.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ void RunTimeLambdaProxyClassInfo::init(LambdaProxyClassKey& key, DumpTimeLambdaP
9292
}
9393

9494
DumpTimeLambdaProxyClassDictionary* LambdaProxyClassDictionary::_dumptime_table = nullptr;
95+
LambdaProxyClassDictionary LambdaProxyClassDictionary::_runtime_table_for_dumping;
9596
LambdaProxyClassDictionary LambdaProxyClassDictionary::_runtime_static_table; // for static CDS archive
9697
LambdaProxyClassDictionary LambdaProxyClassDictionary::_runtime_dynamic_table; // for dynamic CDS archive
9798

@@ -425,7 +426,7 @@ class CopyLambdaProxyClassInfoToArchive : StackObj {
425426
};
426427

427428
void LambdaProxyClassDictionary::write_dictionary(bool is_static_archive) {
428-
LambdaProxyClassDictionary* dictionary = is_static_archive ? &_runtime_static_table : &_runtime_dynamic_table;
429+
LambdaProxyClassDictionary* dictionary = &_runtime_table_for_dumping;
429430
CompactHashtableStats stats;
430431
dictionary->reset();
431432
CompactHashtableWriter writer(_dumptime_table->_count, &stats);

src/hotspot/share/cds/lambdaProxyClassDictionary.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ class LambdaProxyClassDictionary : public OffsetCompactHashtable<
269269
private:
270270
class CleanupDumpTimeLambdaProxyClassTable;
271271
static DumpTimeLambdaProxyClassDictionary* _dumptime_table;
272+
static LambdaProxyClassDictionary _runtime_table_for_dumping;
272273
static LambdaProxyClassDictionary _runtime_static_table; // for static CDS archive
273274
static LambdaProxyClassDictionary _runtime_dynamic_table; // for dynamic CDS archive
274275

@@ -319,7 +320,9 @@ class LambdaProxyClassDictionary : public OffsetCompactHashtable<
319320
}
320321

321322
static void serialize(SerializeClosure* soc, bool is_static_archive) {
322-
if (is_static_archive) {
323+
if (soc->writing()) {
324+
_runtime_table_for_dumping.serialize_header(soc);
325+
} else if (is_static_archive) {
323326
_runtime_static_table.serialize_header(soc);
324327
} else {
325328
_runtime_dynamic_table.serialize_header(soc);

src/hotspot/share/classfile/stringTable.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ typedef CompactHashtable<
8686
StringTable::read_string_from_compact_hashtable,
8787
StringTable::wrapped_string_equals> SharedStringTable;
8888

89-
static SharedStringTable _shared_table;
89+
static SharedStringTable _shared_table, _shared_table_for_dumping;
9090
#endif
9191

9292
// --------------------------------------------------------------------------
@@ -961,7 +961,7 @@ void StringTable::write_shared_table() {
961961
precond(CDSConfig::is_dumping_heap());
962962
assert(HeapShared::is_writing_mapping_mode(), "not used for streamed oops");
963963

964-
_shared_table.reset();
964+
_shared_table_for_dumping.reset();
965965
CompactHashtableWriter writer((int)items_count_acquire(), ArchiveBuilder::string_stats());
966966

967967
auto copy_into_shared_table = [&] (WeakHandle* val) {
@@ -974,17 +974,16 @@ void StringTable::write_shared_table() {
974974
return true;
975975
};
976976
_local_table->do_safepoint_scan(copy_into_shared_table);
977-
writer.dump(&_shared_table, "string");
977+
writer.dump(&_shared_table_for_dumping, "string");
978978
}
979979

980980
void StringTable::serialize_shared_table_header(SerializeClosure* soc) {
981-
_shared_table.serialize_header(soc);
981+
SharedStringTable* table = soc->reading() ? &_shared_table : &_shared_table_for_dumping;
982982

983-
if (soc->writing()) {
984-
// Sanity. Make sure we don't use the shared table at dump time
985-
_shared_table.reset();
986-
} else if (!AOTMappedHeapLoader::is_in_use()) {
987-
_shared_table.reset();
983+
table->serialize_header(soc);
984+
if (soc->reading() && !AOTMappedHeapLoader::is_in_use()) {
985+
// AOTStreamedHeapLoader does not use _shared_table.
986+
table->reset();
988987
}
989988
}
990989

src/hotspot/share/classfile/systemDictionaryShared.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@
7979
#include "utilities/hashTable.hpp"
8080
#include "utilities/stringUtils.hpp"
8181

82-
SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_static_archive;
83-
SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_dynamic_archive;
82+
SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_static_archive;
83+
SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_dynamic_archive;
84+
SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_dumping;
8485

8586
DumpTimeSharedClassTable* SystemDictionaryShared::_dumptime_table = nullptr;
8687

@@ -132,8 +133,8 @@ InstanceKlass* SystemDictionaryShared::lookup_from_stream(Symbol* class_name,
132133
return nullptr;
133134
}
134135

135-
const RunTimeClassInfo* record = find_record(&_static_archive._unregistered_dictionary,
136-
&_dynamic_archive._unregistered_dictionary,
136+
const RunTimeClassInfo* record = find_record(&_info_for_static_archive._unregistered_dictionary,
137+
&_info_for_dynamic_archive._unregistered_dictionary,
137138
class_name);
138139
if (record == nullptr) {
139140
return nullptr;
@@ -701,7 +702,7 @@ void SystemDictionaryShared::copy_unregistered_class_size_and_crc32(InstanceKlas
701702
precond(klass->in_aot_cache());
702703

703704
// A shared class must have a RunTimeClassInfo record
704-
const RunTimeClassInfo* record = find_record(&_static_archive._unregistered_dictionary,
705+
const RunTimeClassInfo* record = find_record(&_info_for_static_archive._unregistered_dictionary,
705706
nullptr, klass->name());
706707
precond(record != nullptr);
707708
precond(record->klass() == klass);
@@ -1335,7 +1336,7 @@ void SystemDictionaryShared::write_dictionary(RunTimeSharedDictionary* dictionar
13351336
}
13361337

13371338
void SystemDictionaryShared::write_to_archive(bool is_static_archive) {
1338-
ArchiveInfo* archive = get_archive(is_static_archive);
1339+
ArchiveInfo* archive = get_archive(is_static_archive, /*is_dumping=*/true);
13391340

13401341
write_dictionary(&archive->_builtin_dictionary, true);
13411342
write_dictionary(&archive->_unregistered_dictionary, false);
@@ -1348,7 +1349,7 @@ void SystemDictionaryShared::write_to_archive(bool is_static_archive) {
13481349

13491350
void SystemDictionaryShared::serialize_dictionary_headers(SerializeClosure* soc,
13501351
bool is_static_archive) {
1351-
ArchiveInfo* archive = get_archive(is_static_archive);
1352+
ArchiveInfo* archive = get_archive(is_static_archive, soc->writing());
13521353

13531354
archive->_builtin_dictionary.serialize_header(soc);
13541355
archive->_unregistered_dictionary.serialize_header(soc);
@@ -1395,8 +1396,8 @@ SystemDictionaryShared::find_record(RunTimeSharedDictionary* static_dict, RunTim
13951396
}
13961397

13971398
InstanceKlass* SystemDictionaryShared::find_builtin_class(Symbol* name) {
1398-
const RunTimeClassInfo* record = find_record(&_static_archive._builtin_dictionary,
1399-
&_dynamic_archive._builtin_dictionary,
1399+
const RunTimeClassInfo* record = find_record(&_info_for_static_archive._builtin_dictionary,
1400+
&_info_for_dynamic_archive._builtin_dictionary,
14001401
name);
14011402
if (record != nullptr) {
14021403
assert(!record->klass()->is_hidden(), "hidden class cannot be looked up by name");
@@ -1437,11 +1438,12 @@ const char* SystemDictionaryShared::loader_type_for_shared_class(Klass* k) {
14371438
}
14381439

14391440
void SystemDictionaryShared::get_all_archived_classes(bool is_static_archive, GrowableArray<Klass*>* classes) {
1440-
get_archive(is_static_archive)->_builtin_dictionary.iterate_all([&] (const RunTimeClassInfo* record) {
1441+
ArchiveInfo* archive = get_archive(is_static_archive, /*is_dumping=*/false);
1442+
archive->_builtin_dictionary.iterate_all([&] (const RunTimeClassInfo* record) {
14411443
classes->append(record->klass());
14421444
});
14431445

1444-
get_archive(is_static_archive)->_unregistered_dictionary.iterate_all([&] (const RunTimeClassInfo* record) {
1446+
archive->_unregistered_dictionary.iterate_all([&] (const RunTimeClassInfo* record) {
14451447
classes->append(record->klass());
14461448
});
14471449
}
@@ -1488,10 +1490,10 @@ void SystemDictionaryShared::ArchiveInfo::print_table_statistics(const char* pre
14881490
void SystemDictionaryShared::print_shared_archive(outputStream* st, bool is_static) {
14891491
if (CDSConfig::is_using_archive()) {
14901492
if (is_static) {
1491-
_static_archive.print_on("", st, true);
1493+
_info_for_static_archive.print_on("", st, true);
14921494
} else {
14931495
if (DynamicArchive::is_mapped()) {
1494-
_dynamic_archive.print_on("Dynamic ", st, false);
1496+
_info_for_dynamic_archive.print_on("Dynamic ", st, false);
14951497
}
14961498
}
14971499
}
@@ -1504,9 +1506,9 @@ void SystemDictionaryShared::print_on(outputStream* st) {
15041506

15051507
void SystemDictionaryShared::print_table_statistics(outputStream* st) {
15061508
if (CDSConfig::is_using_archive()) {
1507-
_static_archive.print_table_statistics("Static ", st, true);
1509+
_info_for_static_archive.print_table_statistics("Static ", st, true);
15081510
if (DynamicArchive::is_mapped()) {
1509-
_dynamic_archive.print_table_statistics("Dynamic ", st, false);
1511+
_info_for_dynamic_archive.print_table_statistics("Dynamic ", st, false);
15101512
}
15111513
}
15121514
}

src/hotspot/share/classfile/systemDictionaryShared.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,16 @@ class SystemDictionaryShared: public SystemDictionary {
150150
class ExclusionCheckCandidates;
151151
static DumpTimeSharedClassTable* _dumptime_table;
152152

153-
static ArchiveInfo _static_archive;
154-
static ArchiveInfo _dynamic_archive;
155-
156-
static ArchiveInfo* get_archive(bool is_static_archive) {
157-
return is_static_archive ? &_static_archive : &_dynamic_archive;
153+
static ArchiveInfo _info_for_static_archive;
154+
static ArchiveInfo _info_for_dynamic_archive;
155+
static ArchiveInfo _info_for_dumping;
156+
157+
static ArchiveInfo* get_archive(bool is_static_archive, bool is_dumping) {
158+
if (is_dumping) {
159+
return &_info_for_dumping;
160+
} else {
161+
return is_static_archive ? &_info_for_static_archive : &_info_for_dynamic_archive;
162+
}
158163
}
159164

160165
static InstanceKlass* load_shared_class_for_builtin_loader(

0 commit comments

Comments
 (0)