Spread problem with > 10 arguments
Fredrik Öhrström
fredrik.ohrstrom at oracle.com
Sat Jul 11 01:20:17 PDT 2009
Rémi Forax skrev:
> It's surely a stupid question but I don't understand
> how the VM knows that such generic method exists.
>
Hmm, there are no generic methods. :-)
Generic invocation, is simply that the JVM
will allow a methodhandle callsite to
successfully call a target where the
arguments do not match exactly.
This is actually the case in normal Java.
For example, if you have the method:
void update(long x)
you can call it with
obj.update((int)42);
// i2l conversion at callsite
and if you have:
void print(Object o)
you can call it with
obj.print("Hello");
// upcast (ie no-op) at callsite
and with:
obj.print(42);
// autoboxing and upcast
These kind of calls are not possible with the
current JSR292 proposal, since it requires
an exact match.
However generic invocation also performs
downcasts and unboxing before entering
the target. This makes it possible to
have the target:
void print(String x);
and call it with:
mh.invoke<void>((Object)"Hello");
// downcast to String,
and the target:
void update(int 42);
and call it with:
mh.invoke<void>((Object)42);
Obviously, the return value is equally treated.
You could say that generic invocation makes
invoke on a methodhandle to behave
more like a Java programmer would expect it
to do. :-)
You can also say that it introduces
covariance/contravariance for the
return value/arguments. (It might look
like it introduces multivariance, but since
anything else than co/contra variance
will cause a class cast exception. The end
result is exactly co/contra variance.)
> Moreover, because generic invocation doesn't create a varargs array,
> Do all adapters need to have 256 methods, because you can have
> potentially a call with 255 arguments ?
>
>
Yes, this is correct. As you can see from my example
implementations of the transforms like GuardWithTest
in my second blog post.
I gave one impl without varargs, will have up to
256 methods. The other with varargs, for more
advanced JVMs has one method.
> I don't agree.
> If you take a look to adapters in MethodHandles, the code is really simple
> and apart convert/spread/collect, you don't need this allocation.
>
> Furthermore, I can see another problem,
> because adapters will internaly calls another method handle using
> MethodHandle.invoke,
> there is a real risk of a cascade of boxing/unboxing if by example one
> method handle out of two
> is a convertArgument.
>
In fact, convertArgument will not be needed since it is,
in effect generic invocation. But as you say, with long
enough transform chains, there is a risk of boxing/unboxing.
But I would say that even a very small interpreting
only JVM would be able to do what you are doing in your
backport. That is, generate an optimized call chain of
bytecode with the correct types built in. This would be
a JVM internal optimization not visible to the outside.
I believe that generic invocation is backwards
compatible with the current design. Nothing needs
to go away except the JavaMethodHandle since it will
no longer be necessary. It makes JSR292 behave
more like Java and most importantly. It gives
the dynamic language runtime programmers the
ability to create their own transforms!
//Fredrik
More information about the mlvm-dev
mailing list