Skip to content

Commit c4b516d

Browse files
calvinccheungiklam
andcommitted
8348322: AOT cache creation crashes with "All cached hidden classes must be aot-linkable" when AOTInvokeDynamicLinking is disabled
Co-authored-by: Ioi Lam <iklam@openjdk.org> Reviewed-by: iklam, matsaave
1 parent e470f47 commit c4b516d

File tree

17 files changed

+48
-34
lines changed

17 files changed

+48
-34
lines changed

src/hotspot/share/cds/aotClassInitializer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
107107
// Automatic selection for aot-inited classes
108108
// ==========================================
109109
//
110-
// When CDSConfig::is_initing_classes_at_dump_time() is enabled,
110+
// When CDSConfig::is_initing_classes_at_dump_time is enabled,
111111
// AOTArtifactFinder::find_artifacts() finds the classes of all
112112
// heap objects that are reachable from HeapShared::_run_time_special_subgraph,
113113
// and mark these classes as aot-inited. This preserves the initialized
@@ -266,7 +266,7 @@ bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
266266
}
267267
}
268268

269-
if (CDSConfig::is_dumping_invokedynamic()) {
269+
if (CDSConfig::is_dumping_method_handles()) {
270270
// This table was created with the help of CDSHeapVerifier.
271271
// Also, some $Holder classes are needed. E.g., Invokers.<clinit> explicitly
272272
// initializes Invokers$Holder. Since Invokers.<clinit> won't be executed

src/hotspot/share/cds/aotClassLinker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ bool AOTClassLinker::try_add_candidate(InstanceKlass* ik) {
142142

143143
if (ik->is_hidden()) {
144144
assert(ik->shared_class_loader_type() != ClassLoader::OTHER, "must have been set");
145-
if (!CDSConfig::is_dumping_invokedynamic()) {
145+
if (!CDSConfig::is_dumping_method_handles()) {
146146
return false;
147147
}
148148
if (HeapShared::is_lambda_proxy_klass(ik)) {

src/hotspot/share/cds/archiveBuilder.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,7 @@ void ArchiveBuilder::make_klasses_shareable() {
786786
const char* aotlinked_msg = "";
787787
const char* inited_msg = "";
788788
Klass* k = get_buffered_addr(klasses()->at(i));
789+
bool inited = false;
789790
k->remove_java_mirror();
790791
#ifdef _LP64
791792
if (UseCompactObjectHeaders) {
@@ -810,7 +811,7 @@ void ArchiveBuilder::make_klasses_shareable() {
810811
InstanceKlass* ik = InstanceKlass::cast(k);
811812
InstanceKlass* src_ik = get_source_addr(ik);
812813
bool aotlinked = AOTClassLinker::is_candidate(src_ik);
813-
bool inited = ik->has_aot_initialized_mirror();
814+
inited = ik->has_aot_initialized_mirror();
814815
ADD_COUNT(num_instance_klasses);
815816
if (CDSConfig::is_dumping_dynamic_archive()) {
816817
// For static dump, class loader type are already set.
@@ -833,7 +834,7 @@ void ArchiveBuilder::make_klasses_shareable() {
833834
type = "bad";
834835
assert(0, "shouldn't happen");
835836
}
836-
if (CDSConfig::is_dumping_invokedynamic()) {
837+
if (CDSConfig::is_dumping_method_handles()) {
837838
assert(HeapShared::is_archivable_hidden_klass(ik), "sanity");
838839
} else {
839840
// Legacy CDS support for lambda proxies
@@ -891,7 +892,11 @@ void ArchiveBuilder::make_klasses_shareable() {
891892
aotlinked_msg = " aot-linked";
892893
}
893894
if (inited) {
894-
inited_msg = " inited";
895+
if (InstanceKlass::cast(k)->static_field_size() == 0) {
896+
inited_msg = " inited (no static fields)";
897+
} else {
898+
inited_msg = " inited";
899+
}
895900
}
896901

897902
MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread::current(), ik);

src/hotspot/share/cds/cdsConfig.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ bool CDSConfig::_is_using_optimized_module_handling = true;
4747
bool CDSConfig::_is_dumping_full_module_graph = true;
4848
bool CDSConfig::_is_using_full_module_graph = true;
4949
bool CDSConfig::_has_aot_linked_classes = false;
50-
bool CDSConfig::_has_archived_invokedynamic = false;
5150
bool CDSConfig::_old_cds_flags_used = false;
5251
bool CDSConfig::_new_aot_flags_used = false;
5352
bool CDSConfig::_disable_heap_dumping = false;
@@ -738,8 +737,13 @@ bool CDSConfig::is_dumping_invokedynamic() {
738737
return AOTInvokeDynamicLinking && is_dumping_aot_linked_classes() && is_dumping_heap();
739738
}
740739

741-
bool CDSConfig::is_loading_invokedynamic() {
742-
return UseSharedSpaces && is_using_full_module_graph() && _has_archived_invokedynamic;
740+
// When we are dumping aot-linked classes and we are able to write archived heap objects, we automatically
741+
// enable the archiving of MethodHandles. This will in turn enable the archiving of MethodTypes and hidden
742+
// classes that are used in the implementation of MethodHandles.
743+
// Archived MethodHandles are required for higher-level optimizations such as AOT resolution of invokedynamic
744+
// and dynamic proxies.
745+
bool CDSConfig::is_dumping_method_handles() {
746+
return is_initing_classes_at_dump_time();
743747
}
744748

745749
#endif // INCLUDE_CDS_JAVA_HEAP

src/hotspot/share/cds/cdsConfig.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class CDSConfig : public AllStatic {
4141
static bool _is_dumping_full_module_graph;
4242
static bool _is_using_full_module_graph;
4343
static bool _has_aot_linked_classes;
44-
static bool _has_archived_invokedynamic;
4544

4645
static char* _default_archive_path;
4746
static char* _static_archive_path;
@@ -160,8 +159,7 @@ class CDSConfig : public AllStatic {
160159
static bool is_initing_classes_at_dump_time() NOT_CDS_JAVA_HEAP_RETURN_(false);
161160

162161
static bool is_dumping_invokedynamic() NOT_CDS_JAVA_HEAP_RETURN_(false);
163-
static bool is_loading_invokedynamic() NOT_CDS_JAVA_HEAP_RETURN_(false);
164-
static void set_has_archived_invokedynamic() { CDS_JAVA_HEAP_ONLY(_has_archived_invokedynamic = true); }
162+
static bool is_dumping_method_handles() NOT_CDS_JAVA_HEAP_RETURN_(false);
165163

166164
// full_module_graph (requires optimized_module_handling)
167165
static bool is_dumping_full_module_graph() { return CDS_ONLY(_is_dumping_full_module_graph) NOT_CDS(false); }

src/hotspot/share/cds/cdsHeapVerifier.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0)
106106

107107
ADD_EXCL("java/lang/System", "bootLayer"); // A
108108

109+
ADD_EXCL("java/util/Collections", "EMPTY_LIST"); // E
110+
109111
// A dummy object used by HashSet. The value doesn't matter and it's never
110112
// tested for equality.
111113
ADD_EXCL("java/util/HashSet", "PRESENT"); // E
@@ -127,7 +129,7 @@ CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0)
127129
ADD_EXCL("sun/invoke/util/ValueConversions", "ONE_INT", // E
128130
"ZERO_INT"); // E
129131

130-
if (CDSConfig::is_dumping_invokedynamic()) {
132+
if (CDSConfig::is_dumping_method_handles()) {
131133
ADD_EXCL("java/lang/invoke/InvokerBytecodeGenerator", "MEMBERNAME_FACTORY", // D
132134
"CD_Object_array", // E same as <...>ConstantUtils.CD_Object_array::CD_Object
133135
"INVOKER_SUPER_DESC"); // E same as java.lang.constant.ConstantDescs::CD_Object

src/hotspot/share/cds/classListParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ void ClassListParser::resolve_indy(JavaThread* current, Symbol* class_name_symbo
627627
}
628628

629629
void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) {
630-
if (CDSConfig::is_dumping_invokedynamic()) {
630+
if (CDSConfig::is_dumping_method_handles()) {
631631
// The CP entry for the invokedynamic instruction will be resolved.
632632
// No need to do the following.
633633
return;

src/hotspot/share/cds/filemap.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment,
234234
_use_optimized_module_handling = CDSConfig::is_using_optimized_module_handling();
235235
_has_aot_linked_classes = CDSConfig::is_dumping_aot_linked_classes();
236236
_has_full_module_graph = CDSConfig::is_dumping_full_module_graph();
237-
_has_archived_invokedynamic = CDSConfig::is_dumping_invokedynamic();
238237

239238
// The following fields are for sanity checks for whether this archive
240239
// will function correctly with this JVM and the bootclasspath it's
@@ -309,7 +308,6 @@ void FileMapHeader::print(outputStream* st) {
309308
st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling);
310309
st->print_cr("- has_full_module_graph %d", _has_full_module_graph);
311310
st->print_cr("- has_aot_linked_classes %d", _has_aot_linked_classes);
312-
st->print_cr("- has_archived_invokedynamic %d", _has_archived_invokedynamic);
313311
}
314312

315313
bool FileMapInfo::validate_class_location() {
@@ -1950,10 +1948,6 @@ bool FileMapHeader::validate() {
19501948
if (!_has_full_module_graph) {
19511949
CDSConfig::stop_using_full_module_graph("archive was created without full module graph");
19521950
}
1953-
1954-
if (_has_archived_invokedynamic) {
1955-
CDSConfig::set_has_archived_invokedynamic();
1956-
}
19571951
}
19581952

19591953
return true;

src/hotspot/share/cds/filemap.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ class FileMapHeader: private CDSFileMapHeaderBase {
140140
// some expensive operations.
141141
bool _has_aot_linked_classes; // Was the CDS archive created with -XX:+AOTClassLinking
142142
bool _has_full_module_graph; // Does this CDS archive contain the full archived module graph?
143-
bool _has_archived_invokedynamic; // Does the archive have aot-linked invokedynamic CP entries?
144143
HeapRootSegments _heap_root_segments; // Heap root segments info
145144
size_t _heap_oopmap_start_pos; // The first bit in the oopmap corresponds to this position in the heap.
146145
size_t _heap_ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the heap.

src/hotspot/share/cds/heapShared.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ bool HeapShared::is_string_concat_klass(InstanceKlass* ik) {
492492
}
493493

494494
bool HeapShared::is_archivable_hidden_klass(InstanceKlass* ik) {
495-
return CDSConfig::is_dumping_invokedynamic() &&
495+
return CDSConfig::is_dumping_method_handles() &&
496496
(is_lambda_form_klass(ik) || is_lambda_proxy_klass(ik) || is_string_concat_klass(ik));
497497
}
498498

@@ -782,7 +782,7 @@ void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) {
782782
if (orig_k->is_instance_klass()) {
783783
#ifdef ASSERT
784784
InstanceKlass* ik = InstanceKlass::cast(orig_k);
785-
if (CDSConfig::is_dumping_invokedynamic()) {
785+
if (CDSConfig::is_dumping_method_handles()) {
786786
assert(ik->class_loader() == nullptr ||
787787
HeapShared::is_lambda_proxy_klass(ik),
788788
"we can archive only instances of boot classes or lambda proxy classes");
@@ -835,7 +835,7 @@ void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) {
835835
}
836836

837837
const char* lambda_msg = "";
838-
if (CDSConfig::is_dumping_invokedynamic()) {
838+
if (CDSConfig::is_dumping_method_handles()) {
839839
lambda_msg = ", or a lambda proxy class";
840840
if (HeapShared::is_lambda_proxy_klass(ik) &&
841841
(ik->class_loader() == nullptr ||
@@ -1108,7 +1108,7 @@ void HeapShared::resolve_classes_for_subgraph_of(JavaThread* current, Klass* k)
11081108
}
11091109

11101110
void HeapShared::initialize_java_lang_invoke(TRAPS) {
1111-
if (CDSConfig::is_loading_invokedynamic() || CDSConfig::is_dumping_invokedynamic()) {
1111+
if (CDSConfig::is_using_aot_linked_classes() || CDSConfig::is_dumping_method_handles()) {
11121112
resolve_or_init("java/lang/invoke/Invokers$Holder", true, CHECK);
11131113
resolve_or_init("java/lang/invoke/MethodHandle", true, CHECK);
11141114
resolve_or_init("java/lang/invoke/MethodHandleNatives", true, CHECK);

0 commit comments

Comments
 (0)