Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On signature polymorphic methods in Java-7

As far as I can tell, with the introduction of MethodHandle in Java 7 came the introduction of compiler-generated method overloads.

The javadoc for MethodHandle states (I've trimmed the examples):

Here are some examples of usage:

Object x, y; String s; int i;
mh = ...
// (Ljava/lang/String;CC)Ljava/lang/String;
// (String, char, char) -> String
s = (String) mh.invokeExact("daddy",'d','n');

// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
// (Object, Object, Object) -> Object
x = mh.invokeExact((Object)1, (Object)2, (Object)3);

// (Ljava/util/List;)I
// (List) -> int
i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));

// (Ljava/io/PrintStream;Ljava/lang/String;)V
// (PrintStream, String) -> void
mh.invokeExact(System.out, "Hello, world.");

Each of the above calls generates a single invokevirtual instruction with the name invoke and the type descriptors indicated in the comments. The argument types are taken directly from the actual arguments, while the return type is taken from the cast immediately applied to the call. This cast may be to a primitive. If it is missing, the type defaults to Object if the call occurs in a context which uses the return value. If the call occurs as a statement, a cast is impossible, and there is no return type; the call is void.

In effect, invokeExact and friends behave as if there is an overload for every possible combination of paramaters and return type.

I've heard that MethodHandles are preparing for features in Java 8 like lambdas. (I know they are already useful for scripting languages.)

[/introduction]

So, are there more of these compiler-generated overloads hiding around in Java? Are there hints there will be more of them in the future (say, with extension methods)? Why is it necessary in the first place? Merely speed? How does it help lambdas out (I thought lambdas would compile to an anonymous inner class)?

In short, what's the rationale; why are they (generated overloads) useful now and in the future?

UPDATE: What I call compiler-generated overloads here, the Oracle guys call signature polymophic.

like image 880
Michael Deardeuff Avatar asked Dec 20 '12 18:12

Michael Deardeuff


1 Answers

I just came across an Hotspot internals wiki on MethodHandles and invokedynamic

It makes a few interesting points that answer these questions (and a few more).

  • What is called compiler-generated overloads in the question, the java guys call signature polymorphic.
  • MethodHandle.invokeExact and friends are unique, being the only signature polymorphic methods.
  • On the HotSpot VM, the invokevirtual bytecode for MethodHandle.invoke* is secretly converted to an invokehandle instruction.
    • invokehandle is like invokedynamic; a few internals are different, and where each invokedynamic instruction must point to it's own Constant Pool Cache Entry (CPCE), invokehandles can share CPCEs.
  • invokedynamic uses the non-public MethodHandle.invokeBasic on the HotSpot VM
    • MethodHandle.invokeBasic is like invokeExact but more loose; for one it does not check the types of at the call-site with those of the callee.
  • Hot method handles (including invokedynamic) can be JIT-compiled

Additionally, lambda expressions will be implemented via invokedynamic. (Got that from Edwin Dalorzo's answer.) This means lambda expressions

  • will indirectly use MethodHandle.invokeBasic on the HotSpot VM (see above), and
  • are eligible to be JIT-compiled
like image 82
Michael Deardeuff Avatar answered Sep 21 '22 02:09

Michael Deardeuff