Skip to main content

Calling invokedynamic in Java

Posted by forax on January 7, 2011 at 1:00 PM PST

DynamicIndy

There is no way to invoke invokedynamic using the Java language. So testing invokedynamic is not that obvious if you don't have your own dynamic language.
I've developed a small class DynamicIndy that uses ASM 4.0 (not an official release) to generate a static method that calls invokedynamic. These static method is after converted to a MethodHandle that can be called in Java
The code is available at the bottom of this post

How to use it ?

DynamicIndy defines a method named (judiciously :) invokedynamic that takes a name and a MethodType, a way to specify a bootstrap method (a triple class, method name, method type ) and some optional arguments for the bootstrap method.
The following code shows how to create a BigDecimal constant using invokedynamic.

This code shows how to use it:

 public class DynamicIndyTest {
  public static CallSite bsm(Lookup lookup, String name, MethodType methodType, Object arg) {
    System.out.println("construct the BigDecimal constant "+arg);
    return new ConstantCallSite(
        MethodHandles.constant(BigDecimal.class, new BigDecimal(arg.toString())));
  }
 
  public static void main(String[] args) throws Throwable {
    DynamicIndy dynamicIndy = new DynamicIndy();
    MethodHandle mh = dynamicIndy.invokeDynamic("_", MethodType.methodType(BigDecimal.class),
        DynamicIndyTest.class, "bsm", MethodType.methodType(CallSite.class, Lookup.class, String.class, MethodType.class, Object.class),
        "1234567890.1234567890"
        );
    System.out.println((BigDecimal)mh.invokeExact());
    System.out.println((BigDecimal)mh.invokeExact());
  }
}

If you run this code

java -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic
  -cp .:asm-all-4.0-beta1.jar DynamicIndyTest

it will print

construct the BigDecimal constant 1234567890.1234567890
1234567890.1234567890
1234567890.1234567890 

As you see the bootstrap method is called once and the constant is reused.

cheers,
Rémi

Related Topics >>

Comments

 Hi, Thanks for sharing, this is all very exciting. Is ...

Hi,

Thanks for sharing, this is all very exciting. Is it possible for you to post the code generation for DynamicIndy?

Thanks, Baruch

Very nice. This is more

(Written after I read the example code, edited after I read the ASM code...)
Very nice: Could form the base of a more rigorous alternative to Indify: blogs.sun.com/jrose/entry/a_modest_tool_for_writing
It would be nice to see this grow into something which can be reliably used for the same purposes as Indify. Then it could be java agent which transforms JDK 6 to JDK 7, the inverse of the backport. We won't have Java language support for method handle constants and invokedynamic until (probably) JDK 8, so we'll have to fake it various ways in JDK 7.
This proof of concept is a one-shot generator of a single-purpose class wrapped around a single indy instruction.
In order to reweave JDK6 bytecode expressions into JDK7 invokedynamic expressions, a partial decompiler is needed. Expressions which might be transformable to invokedynamic instructions would have to be recognized and replaced in the bytecodes. The Indify tool performs a shoddy, incomplete analysis of this sort, but surely there are better ASM-based tools to do the same thing, with industrial strength.
The static analysis of such a reweaver could cope (if desired) with common patterns of hoisting and caching that users might use to avoid the expense of repeated lookups.
-- John