Adopting JEP 303 (Intrinsics for LDC and INVOKEDYNAMIC) into Amber

Brian Goetz brian.goetz at oracle.com
Fri Apr 21 11:37:51 UTC 2017


Does it work if you get rid of the class literals, and use strings?

On 4/21/2017 1:03 AM, Tagir Valeev wrote:
> Seems that it does not work if I use intermediate variable for 
> MethodTypeConstant. Consider the following code:
>
> import java.lang.invoke.*;
> import static java.lang.invoke.Constables.*;
> import static java.lang.invoke.Intrinsics.*;
>
> public class TestConst {
>     public static void main(String[] args) throws Throwable {
>         MethodTypeConstant mtc = MethodTypeConstant.of(void.class);
>         MethodHandleConstant mhc = 
> MethodHandleConstant.ofStatic(TestConst.class, "test", mtc);
>         MethodHandle mh = Intrinsics.ldc(mhc);
>         mh.invokeExact();
>     }
>
>     static void test() {
>         System.out.println("Hello");
>     }
> }
>
> It's compiled without errors and ldc intrinsic is generated correctly. 
> However for non-intrinsified variables class type is not wrapped into 
> ClassConstant:
>
>        0: getstatic     #2                  // Field 
> void.class:Ljava/lang/Class;
>        3: iconst_0
>        4: anewarray     #3                  // class 
> java/lang/invoke/Constables$ClassConstant
>        7: invokestatic  #4                  // Method 
> java/lang/invoke/Constables$MethodTypeConstant.of:(Ljava/lang/invoke/Constables$ClassConstant;[Ljava/lang/invoke/Constables$ClassConstant;)Ljava/lang/invoke/Constables$MethodTypeConstant;
>
> This, of course, results in verification errors:
>
> Exception in thread "main" java.lang.VerifyError: Bad type on operand 
> stack
> Exception Details:
>   Location:
>     TestConst.main([Ljava/lang/String;)V @7: invokestatic
>   Reason:
>     Type 'java/lang/Class' (current frame, stack[0]) is not assignable 
> to 'java/lang/invoke/Constables$ClassConstant'
>   Current Frame:
>     bci: @7
>     flags: { }
>     locals: { '[Ljava/lang/String;' }
>     stack: { 'java/lang/Class', 
> '[Ljava/lang/invoke/Constables$ClassConstant;' }
>
> Probably it would be easier to declare class Class<T> as implements 
> Constable<Class<T>> and replace ClassConstant with Constable<Class<?>> 
> in method signatures where applicable? Or introduce some intermediate 
> interface?
>
> With best regards,
> Tagir Valeev.
>
>
> On Fri, Apr 21, 2017 at 10:47 AM, Tagir Valeev <amaembo at gmail.com 
> <mailto:amaembo at gmail.com>> wrote:
>
>     Thanks! Works fine for me.
>
>     With best regards,
>     Tagir Valeev.
>
>     On Thu, Apr 20, 2017 at 8:37 PM, Vicente Romero
>     <vicente.romero at oracle.com <mailto:vicente.romero at oracle.com>> wrote:
>
>         Hi all,
>
>         I have just pushed a patch that converts class literals into a
>         poly expression. Meaning that now you can pass a class literal
>         where a ClassConstant is expected. This will simplify the use
>         of the API making the user code less verbose. Taking as an
>         example the test case sent by Tagir, it could be now rewritten as:
>
>         import java.lang.invoke.*;
>         import java.lang.invoke.Constables.*;
>         import java.lang.reflect.*;
>
>         public class MH {
>           private static void test() {
>             System.out.println("Hello");
>           }
>
>           public static void main(String[] args) throws Throwable {
>             final MethodHandle handle = Intrinsics.ldc(
>              MethodHandleConstant.ofStatic(MH.class, "test",
>         MethodTypeConstant.of(void.class)));
>             handle.invokeExact();
>           }
>         }
>
>         Thanks,
>         Vicente
>
>
>
>         On 04/18/2017 11:14 PM, Tagir Valeev wrote:
>>         Thank you for the hint! It also seems that
>>         ClassConstant.of(MH.class) does not work either and
>>         VarHandles are not supported yet. However the following
>>         sample finally worked for me:
>>
>>
>>         import java.lang.invoke.*;
>>         import java.lang.invoke.Constables.*;
>>         import java.lang.reflect.*;
>>
>>         public class MH {
>>           private static void test() {
>>         System.out.println("Hello");
>>           }
>>
>>           public static void main(String[] args) throws Throwable {
>>             final MethodHandle handle = Intrinsics.ldc(
>>          MethodHandleConstant.ofStatic(ClassConstant.of("LMH;"),
>>         "test", MethodTypeConstant.of(ClassConstant.of("V"))));
>>             handle.invokeExact();
>>           }
>>         }
>>
>>         With best regards,
>>         Tagir Valeev.
>>
>>
>>         On Tue, Apr 18, 2017 at 9:13 PM, Brian Goetz
>>         <brian.goetz at oracle.com <mailto:brian.goetz at oracle.com>> wrote:
>>
>>             The primitive fields (Constables.VOID and friends) are
>>             not yet hooked up; for the time being, replace with
>>             ClassConstant.of("V").
>>
>>
>>             On 4/18/2017 2:17 AM, Tagir Valeev wrote:
>>
>>                 Hello!
>>
>>                 I tried to play with this, but still no success.
>>                 Fresh build from
>>                 constant-folding branch. I tried to compile the
>>                 following files:
>>
>>                 // MH.java
>>
>>                 import java.lang.invoke.*;
>>                 import java.lang.invoke.Constables.*;
>>                 import java.lang.reflect.*;
>>
>>                 public class MH {
>>                    private static void test() {
>>                  System.out.println("Hello");
>>                    }
>>
>>
>>                    public static void main(String[] args) throws
>>                 Throwable {
>>                      final MethodHandle handle = Intrinsics.ldc(
>>                 MethodHandleConstant.ofStatic(ClassConstant.of(MH.class),
>>                 "test",
>>                 MethodTypeConstant.of(Constables.VOID)));
>>                      handle.invokeExact();
>>                    }
>>
>>                 }
>>
>>                 // VH.java
>>                 import java.lang.invoke.*;
>>                 import java.lang.invoke.Constables.*;
>>                 import java.lang.reflect.*;
>>
>>                 public class VH {
>>                    private static volatile int counter;
>>
>>                    private static final VarHandle COUNTER =
>>                 Intrinsics.ldc(
>>                 VarHandleConstant.ofStaticField(ClassConstant.of(VH.class),
>>                 "counter",
>>                 Constables.INT));
>>
>>                    public static void main(String[] args) {
>>                  System.out.println(COUNTER.getAndAdd(1));
>>                  System.out.println(COUNTER.getAndAdd(1));
>>                    }
>>                 }
>>
>>                 Building with "javac -XDdoConstantFold=true MH.java"
>>                 or "javac
>>                 -XDdoConstantFold=true VH.java",
>>                 javac silently exists without producing .class file
>>                 or reporting any error.
>>                 Tried with -verbose, the output ends like this:
>>
>>                 [loading
>>                 /modules/java.base/java/lang/annotation/RetentionPolicy.class]
>>                 [loading
>>                 /modules/java.base/java/lang/annotation/Target.class]
>>                 [loading
>>                 /modules/java.base/java/lang/annotation/ElementType.class]
>>                 [checking VH]
>>                 [loading /modules/java.base/java/io/Serializable.class]
>>                 [loading
>>                 /modules/java.base/java/lang/AutoCloseable.class]
>>                 [loading /modules/java.base/java/lang/Class.class]
>>                 [loading
>>                 /modules/java.base/java/lang/invoke/Constable.class]
>>                 [loading
>>                 /modules/java.base/java/lang/invoke/Intrinsics.class]
>>                 [total 1484ms]
>>
>>                 Without -XDdoConstantFold=true the class file is
>>                 produced and dies like
>>
>>                 Exception in thread "main"
>>                 java.lang.UnsupportedOperationException: no
>>                 reflective access
>>                 at java.base/java.lang.invoke.Int
>>                 <http://java.lang.invoke.Int>rinsics.ldc(Intrinsics.java:42)
>>                 at MH.main(MH.java:12)
>>
>>                 Which is expected behavior, I guess.
>>
>>                 Am I doing something wrong? Could you compile these
>>                 files on your side?
>>                 Sorry if my tries look lame: I'm very new to this.
>>
>>                 With best regards,
>>                 Tagir Valeev.
>>
>>                 On Tue, Apr 18, 2017 at 9:07 AM, Vicente Romero
>>                 <vicente.romero at oracle.com
>>                 <mailto:vicente.romero at oracle.com>>
>>                 wrote:
>>
>>                     Hi,
>>
>>                     Support for JEP 303 has been pushed in the amber
>>                     repo [1, 2] (branch name
>>                     is 'constant-folding'). The development is mature
>>                     although there are some
>>                     fresh areas like using reflection for accessing
>>                     the API methods. Reflection
>>                     is needed as the classes defined in the API see
>>                     [1] are not available in
>>                     the boot JDK. There is still some ongoing
>>                     research so some changes to the
>>                     API and the code are to be expected in the near
>>                     future,
>>
>>                     Thanks,
>>                     Vicente
>>
>>
>>                     [1]
>>                     http://hg.openjdk.java.net/amber/amber/jdk/rev/2eeb80b82c9c
>>                     <http://hg.openjdk.java.net/amber/amber/jdk/rev/2eeb80b82c9c>
>>                     [2]
>>                     http://hg.openjdk.java.net/amber/amber/langtools/rev/7be70b52c760
>>                     <http://hg.openjdk.java.net/amber/amber/langtools/rev/7be70b52c760>
>>
>>
>>                     On 04/17/2017 04:22 PM, Brian Goetz wrote:
>>
>>                         JEP 303 (Intrinsics for LDC and
>>                         INVOKEDYNAMIC) is hereby adopted into
>>                         Project Amber.
>>
>>                         A first draft of the API can be found at:
>>
>>                         http://cr.openjdk.java.net/~briangoetz/JDK-8178320/webrev/
>>                         <http://cr.openjdk.java.net/%7Ebriangoetz/JDK-8178320/webrev/>
>>
>>                         Prototype implementation coming soon.
>>
>>
>>
>>
>>
>
>
>



More information about the amber-dev mailing list