Couldn't find any obvious problems.  Looks good.

-- Chris

On Jul 2, 2013, at 6:26 PM, John Rose <john.r.r...@oracle.com> wrote:

> Thanks for the helpful review, Vladimir.
> 
> I have incorporated all your comments and updated the webrev here:
> 
>  http://cr.openjdk.java.net/~jrose/8008688/webrev.05
> 
> Detailed replies follow.
> 
> On Jul 1, 2013, at 3:36 PM, Vladimir Ivanov <vladimir.x.iva...@oracle.com> 
> wrote:
> 
>> John,
>> 
>> I have some minor suggestions about code style and code readability.
>> Otherwise, the change looks good!
>> 
>> src/share/classes/java/lang/invoke/MemberName.java:
>>    public MemberName(Method m, boolean wantSpecial) {
>> ...
>>        MethodHandleNatives.init(this, m);
>> +        if (clazz == null) {  // MHN.init failed
>> +            if (m.getDeclaringClass() == MethodHandle.class &&
>> +                isMethodHandleInvokeName(m.getName())) {
>> 
>> Please, add a comment with a short description why a custom init procedure 
>> for MH.invoke* cases is needed.
> 
> Done:
>                // The JVM did not reify this signature-polymorphic instance.
>                // Need a special case here.
>                // See comments on MethodHandleNatives.linkMethod.
> 
> And I added several paragraphs in the javadoc for linkMethod.
> They cover non-reification, linker methods, appendixes, "synthetic", varargs, 
> and more.
> 
>> +    /** Create a name for a signature-polymorphic invoker. */
>> +    static MemberName makeMethodHandleInvoke(String name, MethodType type) {
>> +        return makeMethodHandleInvoke(name, type, MH_INVOKE_MODS | 
>> SYNTHETIC);
>> 
>> Please, add a comment why SYNTHETIC flag is necessary.
> 
>    /**
>     * Create a name for a signature-polymorphic invoker.
>     * This is a placeholder for a signature-polymorphic instance
>     * (of MH.invokeExact, etc.) that the JVM does not reify.
>     * See comments on {@link MethodHandleNatives#linkMethod}.
>     */
> 
>> src/share/classes/java/lang/invoke/MethodHandleInfo.java:
>> src/share/classes/java/lang/invoke/MethodHandles.java:
>> 
>> +import java.security.*;
>> 
>> This import isn't used.
> 
> Fixed.
> 
>> src/share/classes/java/lang/invoke/MethodHandles.java:
>> 
>> +        public MethodHandleInfo revealDirect(MethodHandle target) {
>> ...
>> +            byte refKind = member.getReferenceKind();
>> ...
>> +            // Check SM permissions and member access before cracking.
>> +            try {
>> +                //@@checkSecurityManager(defc, member, lookupClass());
>> +                checkSecurityManager(defc, member);
>> +                checkAccess(member.getReferenceKind(), defc, member);
>> +            } catch (IllegalAccessException ex) {
>> +                throw new IllegalArgumentException(ex);
>> +            }
>> 
>> You prepare a separate refKind for MethodHandleInfo, but perform security 
>> checks against original member.getReferenceKind(). Is it intentional?
> 
> No, it's bug.  Thanks for catching that.
> 
>> src/share/classes/java/lang/invoke/InfoFromMemberName.java:
>> 
>> 81     public <T extends Member> T reflectAs(Class<T> expected, Lookup 
>> lookup) {
>> 82         if (member.isMethodHandleInvoke() && !member.isVarargs()) {
>> 83             // this member is an instance of a signature-polymorphic 
>> method, which cannot be reflected
>> 84             throw new IllegalArgumentException("cannot reflect signature 
>> polymorphic method");
>> 
>> Please, add a comment why (!member.isVarargs()) check is necessary.
> 
>            // This member is an instance of a signature-polymorphic method, 
> which cannot be reflected
>            // A method handle invoker can come in either of two forms:
>            // A generic placeholder (present in the source code, and varargs)
>            // and a signature-polymorphic instance (synthetic and not 
> varargs).
>            // For more information see comments on {@link 
> MethodHandleNatives#linkMethod}.
> 
> 
>> src/share/classes/java/lang/invoke/InfoFromMemberName.java:
>> 
>> 127     private void checkAccess(Member mem, Lookup lookup) throws 
>> IllegalAccessException {
>> 128         byte refKind = (byte) getReferenceKind();
>> 129         if (mem instanceof Method) {
>> 130             boolean wantSpecial = (refKind == REF_invokeSpecial);
>> 131             lookup.checkAccess(refKind, getDeclaringClass(), new 
>> MemberName((Method) mem, wantSpecial));
>> 132         } else if (mem instanceof Constructor) {
>> 133             lookup.checkAccess(refKind, getDeclaringClass(), new 
>> MemberName((Constructor) mem));
>> 134         } else if (mem instanceof Field) {
>> 135             boolean isSetter = (refKind == REF_putField || refKind == 
>> REF_putStatic);
>> 136             lookup.checkAccess(refKind, getDeclaringClass(), new 
>> MemberName((Field) mem, isSetter));
>> 137         }
>> 138     }
>> 
>> Can you introduce a factory method to convert a Member instance into 
>> MemberName and call lookup.checkAccess(refKind, getDeclaringClass(), 
>> covertToMemberName(mem)) instead? It'll considerably simplify the code and 
>> make the intention clearer.
> 
> Good idea.  Done.
> 
> — John
> 
>> Best regards,
>> Vladimir Ivanov
>> 
>> On 6/27/13 10:00 AM, John Rose wrote:
>>> This change implements the MethodHandleInfo API for cracking a direct 
>>> method handle back into its symbolic reference components.  A DMH is any 
>>> CONSTANT_MethodHandle or any result of a Lookup.find* or Lookup.unreflect* 
>>> API call.
>>> 
>>> http://cr.openjdk.java.net/~jrose/8008688/webrev.04
>>> 
>>> Problem:
>>> 
>>> JDK 8 (esp. Project Lambda) needs a stable API for "cracking" 
>>> CONSTANT_MethodHandle constants that are involved with lambda capture sites 
>>> (which are implemented with invokedynamic).
>>> 
>>> Solution:
>>> 
>>> Create, specify, implement, and test such an API.  Run the API design past 
>>> the 292 EG, the Project Lambda folks, and the Oracle internal review 
>>> council (CCC).
>>> 
>>> Testing:
>>> 
>>> Regular JSR 292 regression tests, plus a new jtreg test with positive and 3 
>>> kinds of negative tests, in hundreds of combinations.  (See below.)
>>> 
>>> — John
>>> 
>>> P.S. Output from RevealDirectTest.java.  (It runs with and without a 
>>> security manager.)
>>> 
>>> @Test testSimple executed 107 positive tests in 446 ms
>>> @Test testPublicLookup/1 executed 56 positive tests in 99 ms
>>> @Test testPublicLookup/2 executed 80 positive tests in 551 ms
>>> @Test testPublicLookup/3 executed 56 positive tests in 47 ms
>>> @Test testPublicLookupNegative/1 executed 23/0/0 negative tests in 2 ms
>>> @Test testPublicLookupNegative/2 executed 0/27/0 negative tests in 4 ms
>>> @Test testPublicLookupNegative/3 executed 0/0/27 negative tests in 10 ms
>>> @Test testJavaLangClass executed 60 positive tests in 67 ms
>>> @Test testCallerSensitive executed 30 positive tests in 425 ms
>>> @Test testCallerSensitiveNegative executed 12/0/0 negative tests in 1 ms
>>> @Test testMethodHandleNatives executed 4 positive tests in 5 ms
>>> @Test testMethodHandleInvokes/1 executed 640 positive tests in 828 ms
>>> @Test testMethodHandleInvokes/2 executed 640 positive tests in 177 ms
>>> 
>>> _______________________________________________
>>> mlvm-dev mailing list
>>> mlvm-dev@openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>> 
> 
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev@openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to