Adopting JEP 303 (Intrinsics for LDC and INVOKEDYNAMIC) into Amber
Tagir Valeev
amaembo at gmail.com
Fri Apr 21 05:03:53 UTC 2017
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> 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
> > 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>
>> 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.Intrinsics.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>
>>>> 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
>>>>> [2] 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/
>>>>>>
>>>>>> Prototype implementation coming soon.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>
>>
>>
>
More information about the amber-dev
mailing list