MH inlining fails for a package-private and protected calls

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Tue Oct 28 11:45:46 UTC 2014


Good catch, Paul!

Your analysis is correct. I came to the same conclusion: inlining 
doesn't happen because LambdaForm$DMH can't access 
MHInlineTest$B::package_x and others.

I'm looking for a proper fix right now. Filed JDK-8062280 [1] to track 
the problem.

Best regards,
Vladimir Ivanov

[1] https://bugs.openjdk.java.net/browse/JDK-8062280

On 10/28/14, 1:25 PM, Paul Sandoz wrote:
> On Oct 27, 2014, at 6:23 PM, Paul Sandoz <Paul.Sandoz at oracle.com> wrote:
>> AFAICT an access control check fails for the lambda form to access the protected method when attempting to inline the method handle.
>>
>
> FWIW below is a hacky patch that makes the inlining work, the intent being just to highlight the access control area.
>
> I don't quite know what the proper fix should be.
>
> The Compile::optimize_inlining method attempts to find the mono morphic target, which in turn needs to resolve the method in the context of the calling class via LinkResolver::resolve_virtual_call_or_null, and that fails. If the method is private then Compile::optimize_inlining skips such checks because the method can be statically bound.
>
> Paul.
>
> diff -r b1c2dd843f24 src/share/vm/interpreter/linkResolver.cpp
> --- a/src/share/vm/interpreter/linkResolver.cpp	Fri Oct 24 12:32:53 2014 +0400
> +++ b/src/share/vm/interpreter/linkResolver.cpp	Tue Oct 28 10:12:48 2014 +0100
> @@ -472,6 +472,33 @@
>     }
>   //  assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
>
> +  {
> +    InstanceKlass* inst = InstanceKlass::cast(ref_klass());
> +    if (inst->is_anonymous()) {
> +      Klass* host_klass = inst->host_klass();
> +      if (host_klass == SystemDictionary::LambdaForm_klass()) {
> +
> +#ifndef PRODUCT
> +        if (PrintOpto && (Verbose || WizardMode)) {
> +          tty->print_cr("Host class of reference class is LambdaForm");
> +          tty->print_cr("LinkResolver::check_method_accessability access to method %s.%s%s from class %s, with resolved class %s\n",
> +                sel_klass->external_name(),
> +                sel_method->name()->as_C_string(),
> +                sel_method->signature()->as_C_string(),
> +                ref_klass->external_name(),
> +                resolved_klass->external_name()
> +                );
> +        }
> +#endif
> +
> +        jint new_flags = flags.as_int();
> +        new_flags = new_flags & (~JVM_ACC_PROTECTED);
> +        new_flags = new_flags | JVM_ACC_PUBLIC;
> +        flags.set_flags(new_flags);
> +      }
> +    }
> +  }
> +
>     if (!Reflection::verify_field_access(ref_klass(),
>                                          resolved_klass(),
>                                          sel_klass(),
> diff -r b1c2dd843f24 src/share/vm/opto/callGenerator.cpp
> --- a/src/share/vm/opto/callGenerator.cpp	Fri Oct 24 12:32:53 2014 +0400
> +++ b/src/share/vm/opto/callGenerator.cpp	Tue Oct 28 10:12:48 2014 +0100
> @@ -822,6 +822,19 @@
>     case vmIntrinsics::_linkToSpecial:
>     case vmIntrinsics::_linkToInterface:
>       {
> +
> +#ifndef PRODUCT
> +      if (PrintOpto && (Verbose || WizardMode)) {
> +        tty->print_cr("CallGenerator::for_method_handle_inline");
> +        tty->print("  Caller: ");
> +        caller->print_name();
> +        tty->cr();
> +        tty->print("  Callee: ");
> +        callee->print_name();
> +        tty->cr();
> +      }
> +#endif
> +
>         // Get MemberName argument:
>         Node* member_name = kit.argument(callee->arg_size() - 1);
>         if (member_name->Opcode() == Op_ConP) {
>


More information about the hotspot-compiler-dev mailing list