idea: MethodHandle#invokeTailCall
Per Bothner
per at bothner.com
Sun May 12 21:27:40 PDT 2013
On 05/11/2013 02:00 AM, Charles Oliver Nutter wrote:
> On Fri, May 10, 2013 at 7:16 PM, Per Bothner <per at bothner.com
> <mailto:per at bothner.com>> wrote:
>
> Fail hard is probably the wrong thing to do - except when debugging.
> I think what you want is the default to not fail if it can't pop
> the stack frame, but that there be a VM option to throw an Error
> or even do a VM abort in those case. You'd run the test suite
> in this mode.
>
> That assumes that there is well-specified a minimal set of
> circumstances in which the inlining is done correctly,
> so a compiler or programmer can count on that, and that this
> set is sufficient for low-overhead tail-call elimination.
>
>
> Making such guarantees would have to be explicit in the JVM spec, and
> then we're sorta back to requiring a hard tail call guarantee (a hard
> inlining guarantee to ensure tail calling happens is just a horse of a
> different color).
Actually, you can do a "hard" tail call without inlining, I think.
You just need to be able to pop stack frames. The VM already needs
to do that for exception handling. Of course doing it this way
is both quiet complicated and a lot slower. But that's probably OK
as long as we can expect inlining in normal usage.
> There is actually a way to force inlining with the newer invokedynamic
> impl: a @ForceInline (I forget the actual name) annotation that the
> LambdaForm stuff uses internally. Now, if that were exposed as a
> standard JVM feature, we could make such a hard guarantee...and then
> we're back to having to tag calls or callees with annotations, which was
> something you wanted to avoid (why, exactly?).
I don't know how to annotation calls. You could annotate callers,
which presumably would then apply to all tailcalls in the method.
You could also annotate a callee, which would presumably apply to
all tailcalls to the method.
I'm actually ok with whatever approach is most likely to actually
get into the JVM! Semantically, "doing a tail-call" is a property
of a specific call, and this neither the caller or callee. You can
reasonably do a tailcall to any method. A plausible approach
is an annotation @OptimizeTailCalls on a method which applies
to any tailcalls in the method. That would work for languages
that specify tail-call-elimination: Specify the annotation
for generated methods, as well as appropriate run-time methods
(such as "apply"). I think it should also work for "delegation"
type scenarios for pure Java applications.
A bonus is @OptimizeTailCalls might clean up some language stack-traces,
at least these where an interpreter method can finish
with a tailcall!
>
> I'll be happy when I can run Kawa with --full-tailcalls
> as the default with at most a minor performance degradation.
> If we don't get there, I'll be satisfied if at least it is
> faster (and simpler!) than the current trampoline-based
> implementation.
>
>
> There's still a tail call patch in the MLVM repo, rotting on the vine. :-)
Whatever is most likely to actually make it into shipping code ...
--
--Per Bothner
per at bothner.com http://per.bothner.com/
More information about the mlvm-dev
mailing list