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