Invokedynamic and recursive method call
Remi Forax
forax at univ-mlv.fr
Wed Jan 7 16:13:48 UTC 2015
On 01/07/2015 10:43 AM, Marcus Lagergren wrote:
> Remi, I tried to reproduce your problem with jdk9 b44. It runs decently fast.
yes, nashorn is fast enough but it can be faster if the JIT was not
doing something stupid.
When the VM inline fibo, because fibo is recursive, the recursive call
is inlined only once,
so the call at depth=2 can not be inlined but should be a classical
direct call.
But if fibo is called through an invokedynamic, instead of emitting a
direct call to fibo,
the JIT generates a code that push the method handle on stack and execute it
like if the metod handle was not constant
(the method handle is constant because the call at depth=1 is inlined !).
> When did it start to regress?
jdk7u40, i believe.
I've created a jar containing some handwritten bytecodes with no
dependency to reproduce the issue easily:
https://github.com/forax/vmboiler/blob/master/test7/fibo7.jar
[forax at localhost test7]$ time /usr/jdk/jdk1.9.0/bin/java -cp fibo7.jar
FiboSample
1836311903
real 0m6.653s
user 0m6.729s
sys 0m0.019s
[forax at localhost test7]$ time /usr/jdk/jdk1.8.0_25/bin/java -cp
fibo7.jar FiboSample
1836311903
real 0m6.572s
user 0m6.591s
sys 0m0.019s
[forax at localhost test7]$ time /usr/jdk/jdk1.7.0_71/bin/java -cp
fibo7.jar FiboSample
1836311903
real 0m6.373s
user 0m6.396s
sys 0m0.016s
[forax at localhost test7]$ time /usr/jdk/jdk1.7.0_25/bin/java -cp
fibo7.jar FiboSample
1836311903
real 0m4.847s
user 0m4.832s
sys 0m0.019s
as you can see, it was faster with a JDK before jdk7u40.
>
> Regards
> Marcus
cheers,
Rémi
>
>> On 30 Dec 2014, at 20:48, Remi Forax <forax at univ-mlv.fr> wrote:
>>
>> Hi guys,
>> I've found a bug in the interaction between the lambda form and inlining algorithm,
>> basically if the inlining heuristic bailout because the method is recursive and already inlined once,
>> instead to emit a code to do a direct call, it revert to do call to linkStatic with the method
>> as MemberName.
>>
>> I think it's a regression because before the introduction of lambda forms,
>> I'm pretty sure that the JIT was emitting a direct call.
>>
>> Step to reproduce with nashorn, run this JavaScript code
>> function fibo(n) {
>> return (n < 2)? 1: fibo(n - 1) + fibo(n - 2)
>> }
>>
>> print(fibo(45))
>>
>> like this:
>> /usr/jdk/jdk1.9.0/bin/jjs -J-XX:+UnlockDiagnosticVMOptions -J-XX:+PrintAssembly fibo.js > log.txt
>>
>> look for a method 'fibo' from the tail of the log, you will find something like this:
>>
>> 0x00007f97e4b4743f: mov $0x76d08f770,%r8 ; {oop(a 'java/lang/invoke/MemberName' = {method} {0x00007f97dcff8e40} 'fibo' '(Ljdk/nashorn/internal/runtime/ScriptFunction;Ljava/lang/Object;I)I' in 'jdk/nashorn/internal/scripts/Script$Recompilation$2$fibo')}
>> 0x00007f97e4b47449: xchg %ax,%ax
>> 0x00007f97e4b4744b: callq 0x00007f97dd0446e0
>>
>> I hope this can be fixed. My demonstration that I can have fibo written with a dynamic language
>> that run as fast as written in Java doesn't work anymore :(
>>
>> cheers,
>> Rémi
>>
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
More information about the mlvm-dev
mailing list