[10] RFR (S): 8188145: MethodHandle resolution should follow JVMS sequence of lookup by name & type before type descriptor resolution

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[10] RFR (S): 8188145: MethodHandle resolution should follow JVMS sequence of lookup by name & type before type descriptor resolution

Vladimir Ivanov
http://cr.openjdk.java.net/~vlivanov/8188145/webrev.00
https://bugs.openjdk.java.net/browse/JDK-8188145

When resolving MethodHandle constants JVM eagerly resolves type
descriptor before doing upcall into JDK which performs method/field
resolution later (using MethodHandleNatives.resolve on symbolic MemberName).

The problem is that according to JVMS, member resolution (and all
exceptions it throws) should precede type descriptor resolution.

Proposed fix does member & type descriptor resolution from JVM first and
then passes symbolic info into JDK (MHN.linkMethodHandleConstant).

The fix is conservative, since JDK repeats method/field resolution on a
freshly created MemberName from symbolic info. But considering there are
additional security-sensitive checks on JDK side, I decided to leave all
optimizations for future enhancements.

Testing: hs-precheckin-comp, hs-tier1, hs-tier2

Best regards,
Vladimir Ivanov
Reply | Threaded
Open this post in threaded view
|

Re: [10] RFR (S): 8188145: MethodHandle resolution should follow JVMS sequence of lookup by name & type before type descriptor resolution

Vladimir Kozlov
Seems fine.

Thanks,
Vladimir

On 12/19/17 7:37 AM, Vladimir Ivanov wrote:

> http://cr.openjdk.java.net/~vlivanov/8188145/webrev.00
> https://bugs.openjdk.java.net/browse/JDK-8188145
>
> When resolving MethodHandle constants JVM eagerly resolves type
> descriptor before doing upcall into JDK which performs method/field
> resolution later (using MethodHandleNatives.resolve on symbolic
> MemberName).
>
> The problem is that according to JVMS, member resolution (and all
> exceptions it throws) should precede type descriptor resolution.
>
> Proposed fix does member & type descriptor resolution from JVM first and
> then passes symbolic info into JDK (MHN.linkMethodHandleConstant).
>
> The fix is conservative, since JDK repeats method/field resolution on a
> freshly created MemberName from symbolic info. But considering there are
> additional security-sensitive checks on JDK side, I decided to leave all
> optimizations for future enhancements.
>
> Testing: hs-precheckin-comp, hs-tier1, hs-tier2
>
> Best regards,
> Vladimir Ivanov
Reply | Threaded
Open this post in threaded view
|

Re: [10] RFR (S): 8188145: MethodHandle resolution should follow JVMS sequence of lookup by name & type before type descriptor resolution

Paul Sandoz
In reply to this post by Vladimir Ivanov
The logic looks good to me: resolving the member name, before resolving it’s type.

Paul.

> On 19 Dec 2017, at 07:37, Vladimir Ivanov <[hidden email]> wrote:
>
> http://cr.openjdk.java.net/~vlivanov/8188145/webrev.00
> https://bugs.openjdk.java.net/browse/JDK-8188145
>
> When resolving MethodHandle constants JVM eagerly resolves type descriptor before doing upcall into JDK which performs method/field resolution later (using MethodHandleNatives.resolve on symbolic MemberName).
>
> The problem is that according to JVMS, member resolution (and all exceptions it throws) should precede type descriptor resolution.
>
> Proposed fix does member & type descriptor resolution from JVM first and then passes symbolic info into JDK (MHN.linkMethodHandleConstant).
>
> The fix is conservative, since JDK repeats method/field resolution on a freshly created MemberName from symbolic info. But considering there are additional security-sensitive checks on JDK side, I decided to leave all optimizations for future enhancements.
>
> Testing: hs-precheckin-comp, hs-tier1, hs-tier2
>
> Best regards,
> Vladimir Ivanov

Reply | Threaded
Open this post in threaded view
|

Re: [10] RFR (S): 8188145: MethodHandle resolution should follow JVMS sequence of lookup by name & type before type descriptor resolution

Vladimir Ivanov
Thanks, Paul & Vladimir!

> The logic looks good to me: resolving the member name, before resolving it’s type.

Want to elaborate here a bit.

Symbolic info from CP entry is placed into a freshly created MemberName
instance. It is done that way to piggyback on logic in
MethodHandles::resolve_MemberName() to do proper member resolution.

An alternative would be to factor out relevant logic from
resolve_MemberName() and pass symbolic info directly, but I tried that
and wasn't satisfied with the results.

After resolution succeeds, type descriptor from member name is resolved.
And that's the *only* piece which is used from resolved member name.
Resolved member name is thrown away and JDK will repeat member
resolution from the very beginning.

Type descriptor resolution is performed on the member name to simplify
dispatching logic on descriptor format (method vs field).

Obvious performance improvement would be to reuse resolved member name
and pass it into JDK to construct the method handle right out of it, but
I decided to play it safe and keep the fix simple by preserving all the
existing checks during MH constant construction.

Best regards,
Vladimir Ivanov

PS: another direction I explored was to pass *symbolic* type descriptor
(as a String and not MethodType/Class) into JDK and delay its resolution
till member resolution is over in MethodHandles::resolve_MemberName().

But it turned out to be very fragile because any call of
MemberName::getType() in between triggers type resolution (and it
happens in surprising places, like checking member name equality).

>> On 19 Dec 2017, at 07:37, Vladimir Ivanov <[hidden email]> wrote:
>>
>> http://cr.openjdk.java.net/~vlivanov/8188145/webrev.00
>> https://bugs.openjdk.java.net/browse/JDK-8188145
>>
>> When resolving MethodHandle constants JVM eagerly resolves type descriptor before doing upcall into JDK which performs method/field resolution later (using MethodHandleNatives.resolve on symbolic MemberName).
>>
>> The problem is that according to JVMS, member resolution (and all exceptions it throws) should precede type descriptor resolution.
>>
>> Proposed fix does member & type descriptor resolution from JVM first and then passes symbolic info into JDK (MHN.linkMethodHandleConstant).
>>
>> The fix is conservative, since JDK repeats method/field resolution on a freshly created MemberName from symbolic info. But considering there are additional security-sensitive checks on JDK side, I decided to leave all optimizations for future enhancements.
>>
>> Testing: hs-precheckin-comp, hs-tier1, hs-tier2
>>
>> Best regards,
>> Vladimir Ivanov
>