@@ -81,6 +81,7 @@ bool AOTConstantPoolResolver::is_resolution_deterministic(ConstantPool* cp, int
8181bool AOTConstantPoolResolver::is_class_resolution_deterministic (InstanceKlass* cp_holder, Klass* resolved_class) {
8282 assert (!is_in_archivebuilder_buffer (cp_holder), " sanity" );
8383 assert (!is_in_archivebuilder_buffer (resolved_class), " sanity" );
84+ assert_at_safepoint (); // try_add_candidate() is called below and requires to be at safepoint.
8485
8586 if (resolved_class->is_instance_klass ()) {
8687 InstanceKlass* ik = InstanceKlass::cast (resolved_class);
@@ -342,7 +343,15 @@ void AOTConstantPoolResolver::maybe_resolve_fmi_ref(InstanceKlass* ik, Method* m
342343 break ;
343344
344345 case Bytecodes::_invokehandle:
345- InterpreterRuntime::cds_resolve_invokehandle (raw_index, cp, CHECK);
346+ if (CDSConfig::is_dumping_method_handles ()) {
347+ ResolvedMethodEntry* method_entry = cp->resolved_method_entry_at (raw_index);
348+ int cp_index = method_entry->constant_pool_index ();
349+ Symbol* sig = cp->uncached_signature_ref_at (cp_index);
350+ Klass* k;
351+ if (check_methodtype_signature (cp (), sig, &k, true )) {
352+ InterpreterRuntime::cds_resolve_invokehandle (raw_index, cp, CHECK);
353+ }
354+ }
346355 break ;
347356
348357 default :
@@ -396,7 +405,7 @@ void AOTConstantPoolResolver::preresolve_indy_cp_entries(JavaThread* current, In
396405// Check the MethodType signatures used by parameters to the indy BSMs. Make sure we don't
397406// use types that have been excluded, or else we might end up creating MethodTypes that cannot be stored
398407// in the AOT cache.
399- bool AOTConstantPoolResolver::check_methodtype_signature (ConstantPool* cp, Symbol* sig, Klass** return_type_ret) {
408+ bool AOTConstantPoolResolver::check_methodtype_signature (ConstantPool* cp, Symbol* sig, Klass** return_type_ret, bool is_invokehandle ) {
400409 ResourceMark rm;
401410 for (SignatureStream ss (sig); !ss.is_done (); ss.next ()) {
402411 if (ss.is_reference ()) {
@@ -409,11 +418,18 @@ bool AOTConstantPoolResolver::check_methodtype_signature(ConstantPool* cp, Symbo
409418 if (SystemDictionaryShared::should_be_excluded (k)) {
410419 if (log_is_enabled (Warning, aot, resolve)) {
411420 ResourceMark rm;
412- log_warning (aot, resolve)(" Cannot aot-resolve Lambda proxy because %s is excluded" , k->external_name ());
421+ log_warning (aot, resolve)(" Cannot aot-resolve %s because %s is excluded" ,
422+ is_invokehandle ? " invokehandle" : " Lambda proxy" ,
423+ k->external_name ());
413424 }
414425 return false ;
415426 }
416427
428+ // cp->pool_holder() must be able to resolve k in production run
429+ precond (CDSConfig::is_dumping_aot_linked_classes ());
430+ precond (SystemDictionaryShared::is_builtin_loader (cp->pool_holder ()->class_loader_data ()));
431+ precond (SystemDictionaryShared::is_builtin_loader (k->class_loader_data ()));
432+
417433 if (ss.at_return_type () && return_type_ret != nullptr ) {
418434 *return_type_ret = k;
419435 }
@@ -471,11 +487,44 @@ bool AOTConstantPoolResolver::check_lambda_metafactory_methodhandle_arg(Constant
471487 return false ;
472488 }
473489
490+ // klass and sigature of the method (no need to check the method name)
474491 Symbol* sig = cp->method_handle_signature_ref_at (mh_index);
492+ Symbol* klass_name = cp->klass_name_at (cp->method_handle_klass_index_at (mh_index));
493+
475494 if (log_is_enabled (Debug, aot, resolve)) {
476495 ResourceMark rm;
477496 log_debug (aot, resolve)(" Checking MethodType of MethodHandle for LambdaMetafactory BSM arg %d: %s" , arg_i, sig->as_C_string ());
478497 }
498+
499+ {
500+ Klass* k = find_loaded_class (Thread::current (), cp->pool_holder ()->class_loader (), klass_name);
501+ if (k == nullptr ) {
502+ // Dumping AOT cache: all classes should have been loaded by FinalImageRecipes::load_all_classes(). k must have
503+ // been a class that was excluded when FinalImageRecipes recorded all classes at the end of the training run.
504+ //
505+ // Dumping static CDS archive: all classes in the classlist have already been loaded, before we resolve
506+ // constants. k must have been a class that was excluded when the classlist was written
507+ // at the end of the training run.
508+ if (log_is_enabled (Warning, aot, resolve)) {
509+ ResourceMark rm;
510+ log_warning (aot, resolve)(" Cannot aot-resolve Lambda proxy because %s is not loaded" , klass_name->as_C_string ());
511+ }
512+ return false ;
513+ }
514+ if (SystemDictionaryShared::should_be_excluded (k)) {
515+ if (log_is_enabled (Warning, aot, resolve)) {
516+ ResourceMark rm;
517+ log_warning (aot, resolve)(" Cannot aot-resolve Lambda proxy because %s is excluded" , k->external_name ());
518+ }
519+ return false ;
520+ }
521+
522+ // cp->pool_holder() must be able to resolve k in production run
523+ precond (CDSConfig::is_dumping_aot_linked_classes ());
524+ precond (SystemDictionaryShared::is_builtin_loader (cp->pool_holder ()->class_loader_data ()));
525+ precond (SystemDictionaryShared::is_builtin_loader (k->class_loader_data ()));
526+ }
527+
479528 return check_methodtype_signature (cp, sig);
480529}
481530
0 commit comments