Just An Application

November 23, 2009

InvokeDynamic And MethodHandles On Snow Leopard: Part Two

Filed under: Java, JSR292, MacOSX, MethodHandles, OpenJDK7, Snow Leopard — Tags: , , , — Simon Lewis @ 8:15 pm

MethodHandles Considered Magical

Invoking the method referenced by a MethodHandle is suprisingly straight forward. Call its invoke() method.

But its only got one publically accessible method and that is

    public MethodType type()

True, but it turns out that a MethodHandle is sufficiently advanced to be indistinguishable from magic, and automatically acquires an invoke() method with a signature corresponding to the method it references !

So you can do this


    import java.dyn.MethodHandle;
    import java.dyn.MethodHandles;
    import java.dyn.MethodType;

    import java.io.PrintStream;

    public final class DynTest
    {
        public static void main(String[] theArgs)
        {
            try 
            {
                MethodType type = MethodType.make(Void.TYPE, String.class);
			
                System.out.print("type == ");
                System.out.println(type);
			
                MethodHandle handle = MethodHandles.lookup().findVirtual(PrintStream.class, "print", type);
			
                System.out.print("handle == ");
                System.out.println(handle);
			
                handle.<void>invoke(System.out, "Hello World via a MethodHandle !\n");
			
            }
            catch (Throwable t) 
            {
                t.printStackTrace();
            }
        }
    }

But Not In The 64-Bit VM

Except that if you try it using the 64-bit VM, you get this.


    Macintosh:tmp simon$ !!
    build/bsd-amd64/j2sdk-image/bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic DynTest
    type == (java.lang.String)void
    handle == print(java.io.PrintStream,java.lang.String)void
    Exception in thread "main" java.lang.AbstractMethodError
        at DynTest.main(DynTest.java:31)

The method

    InterpreterGenerator::generate_abstract_entry(void)

which is defined in the file

    $(JDK7_ROOT)/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp

looks as though it may be something to do with this, especially given this method which is defined in the same file


    // Method handle invoker
    // Dispatch a method of the form java.dyn.MethodHandles::invoke(...)
    address InterpreterGenerator::generate_method_handle_entry(void) {
        if (!EnableMethodHandles) {
            return generate_abstract_entry();
        }
        return generate_abstract_entry(); //6815692//
    }

The 32-bit version defined in the file

    $(JDK7_ROOT)/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp

is a bit different.


    // Method handle invoker
    // Dispatch a method of the form java.dyn.MethodHandles::invoke(...)
    address InterpreterGenerator::generate_method_handle_entry(void) {
        if (!EnableMethodHandles) {
            return generate_abstract_entry();
        }

        address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm);

        return entry_point;
    }

Replacing the 64-bit version with the 32-bit version in a continuing spirit of gung-ho optimism confirms that this is the indeed the code involved in invoking the method. Unfortunately it does so by crashing.

Its obviously time to build a 32-bit JVM.




Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: