Is invokedynamic dynamic enough?
Charles Oliver Nutter
charles.nutter at sun.com
Thu Dec 18 13:10:04 PST 2008
Iulian Dragos wrote:
> If the static types of both the method handle, and the call site have
> to be equal, method handles are only usable in cases when even the
> compiler has enough knowledge to generate a direct 'invoke', on the
> receiver type (ok, a method handle does not care about the method
> name). What is their main use case, then?
It seems your problem case is more of multiple possible target types
entering a dynamic call site. I sympathize. It seems Scala is not immune
to this challenge common to dynamically-typed languages.
In JRuby's case the way I've intended to use invokedynamic is that guard
logic for the invocation type would live in the method pointed at by the
handle. That handle would not only have the fast path logic to call
straight through, but would also have logic to invalidate the original
call site and do a slow path. So rather than dispatching directly to the
eventual target method, we would dispatch to an intermediate, passing
the target method handle along.
This does, I believe, reduce one benefit of invokedynamic: the ability
to eliminate intermediate dispatch code. But given that in a dynamic
language (or in Scala's structural typing) call site invalidation is not
simply predicated on the structure of types in the system but also
predicated on what receiver type is being invoked from call to call, I'm
not sure if there's a better way to do this invalidation at present.
It's also possible that having bound a method directly into a call site,
profiled inlining can happen across that intermediate code, and its
existance would not break such inlining. I don't know enough about the
optimization capabilities of Hotspot and the invokedynamic backend to
know if this is the case.
This also leads to one other concern a few folks have had: invokedynamic
should be bootstrapped on the receiver, not on the caller. If we assume
that a given call site may encounter many different, incompatible types,
then it seems necessary to allow rebinding that site when those new
types are encountered. In one sense, this would make wiring up dynamic
invocation easier, since as long as we knew the JVM would re-bootstrap
for new receiver types, we'd be ok to wire a direct path from the call
site to the target method. But I think it flies in the face of how the
call sites are intended to work...they point at exactly one method
handle, regardless of how many receiver types may be encountered. And
the call site actually does live in the caller class, so bootstrapping
on a receiver type is "too late".
Ultimately I think we'll need to explore the invalidation case in more
depth, since I worry about having to do the invalidation of new receiver
types myself in the target handle before dispatching to the eventual
method (or falling back to a slow path). This area is still a little
fuzzy for me as well.
- Charlie
More information about the mlvm-dev
mailing list