Few questions about invokeDynamic

Rémi Forax forax at univ-mlv.fr
Mon Jan 10 05:32:45 PST 2011


On 01/10/2011 02:02 PM, Christian Thalinger wrote:
> On Nov 9, 2010, at 4:25 PM, Rémi Forax wrote:
>> Here is an example.
>>    If indy has no parameter, it tests void ->  indy return type
>>    If indy has one parameter, it test parameter type ->  return type
>>    If indy name is "spread", a spread/collect is done.
>>
>> Rémi
>>
>> PS: With the new API, all identity methods but the one that take no
>> parameter
>> can be removed and replace by Methodhandles.identity() in the BSM.
> I just got back to this bug and now that InvokeDynamic is gone how can I rewrite that code to work again (without John's Indify magic)?
>
> -- Christian
>

Good question.

First, I don't know if this bug is specific to invokedynamic or if the 
conversion code is shared
between MetodHandle and invokedynamic. If the code is shared, you can 
rewrite it using MethodHandle
because invokedynamic can be rewritten to 
bootstrap().getTarget().invokeExact(...)

The other solution is to use this small class:
http://weblogs.java.net/blog/forax/archive/2011/01/07/call-invokedynamic-java

Basically, the code generates at runtime  a method containing an 
invokedynamic and returns a MethodHandle
created on the method. The main problem is that this code depends on 
ASM. Not sure you want such dependency
in your test suite.

The last solution is to send enough mails to Brian asking him (he 
currently own the Java language token)
to re-introduce a Java syntax for invokedynamic.

Rémi

>> ---------------------------------------------------------------------------------------------------
>> public class ConvertTest {
>>    private static boolean identity(boolean v) {
>>      return v;
>>    }
>>    private static byte identity(byte v) {
>>      return v;
>>    }
>>    private static char identity(char v) {
>>      return v;
>>    }
>>    private static short identity(short v) {
>>      return v;
>>    }
>>    private static int identity(int v) {
>>      return v;
>>    }
>>    private static long identity(long v) {
>>      return v;
>>    }
>>    private static float identity(float v) {
>>      return v;
>>    }
>>    private static double identity(double v) {
>>      return v;
>>    }
>>
>>    private static void identity() { }
>>
>>    private static void assertEquals(Object o, Object o2) {
>>      if (!o.equals(o2))
>>        throw new AssertionError("expected "+ o +" found "+o2);
>>    }
>>
>>    public static void main(String[] args) throws Throwable {
>>      for(int i=0; i<  1000000; i++) {
>>        boolean dummyZ; byte dummyB; short dummyS; char dummyC; int
>> dummyI; long dummyL; float dummyF; double dummyD;
>>
>>
>>        //dummyZ = (boolean)InvokeDynamic.foo();  // void ->  boolean
>>        //dummyI = (int)InvokeDynamic.foo();  // void ->  int
>>
>>        //InvokeDynamic.foo(4);  // int ->  void
>>        InvokeDynamic.spread(4);  // spread: int ->  void
>>
>>        //dummyF = (float)InvokeDynamic.foo(4);  // int ->  float
>>        //dummyD = (double)InvokeDynamic.foo(4);  // int ->  double
>>
>>        //assertEquals(4.0f, (float)InvokeDynamic.foo(4));   // int ->  float
>>      }
>>    }
>>
>>    static {
>>      Linkage.registerBootstrapMethod("bootstrap");
>>    }
>>
>>    private static CallSite bootstrap(Class<?>  declaring, String name,
>> MethodType methodType) throws Throwable {
>>      Lookup lookup = MethodHandles.lookup();
>>
>>      MethodHandle mh;
>>      if (methodType.parameterCount() == 0) {
>>        mh = lookup.findStatic(ConvertTest.class, "identity",
>> MethodType.methodType(void.class));
>>      } else {
>>        Class<?>  type = methodType.parameterType(0);
>>        mh = lookup.findStatic(ConvertTest.class, "identity",
>> MethodType.methodType(type, type));
>>
>>        if ("spread".equals(name)) {
>>          mh = MethodHandles.spreadArguments(mh,
>> methodType.changeParameterType(0, Object[].class));
>>          mh = MethodHandles.collectArguments(mh, methodType);
>>        }
>>      }
>>
>>      mh = mh.asType(methodType);
>>
>>      CallSite cs = new CallSite();
>>      cs.setTarget(mh);
>>      return cs;
>>    }
>> }
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev



More information about the mlvm-dev mailing list