Re: RFR(L): 8008688: Make MethodHandleInfo public

2013-07-02 Thread Christian Thalinger
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(ClassT 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 

Re: RFR(L): 8008688: Make MethodHandleInfo public

2013-07-01 Thread Vladimir Ivanov
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.


+/** 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.


src/share/classes/java/lang/invoke/MethodHandleInfo.java:
src/share/classes/java/lang/invoke/MethodHandles.java:

+import java.security.*;

This import isn't used.


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?


src/share/classes/java/lang/invoke/InfoFromMemberName.java:

81 public T extends Member T reflectAs(ClassT 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.


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.

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 

RFR(L): 8008688: Make MethodHandleInfo public

2013-06-27 Thread John Rose
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