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