State of lambda forms stealing stack frames?
Paul Sandoz
paul.sandoz at oracle.com
Thu Jan 9 03:03:17 PST 2014
On Jan 7, 2014, at 5:11 PM, Jochen Theodorou <blackdrag at gmx.org> wrote:
> Am 07.01.2014 15:35, schrieb Paul Sandoz:
>> Hi,
>>
>> One can slightly improve the situation by doing the following before a fib with a larger value:
>>
>> // 30 is the compile threshold for lambda forms
>> for (int i = 0; i < 30); i++) {
>> fib(10)
>> }
>>
>> // 10000 is the inlining threshold
>> for (int i = 0; i < (30 + 10000); i++) {
>> fib(10)
>> }
>>
>> Although that does not really help matters, just might be interesting in terms of behaviour.
>
> that of course helps.
>
>> AFAICT between calls to fib there are about 3 invoke dynamic instructions and each of those have method handles with fairly substantial lamba forms (suggesting lots of MH chaining), contributing ~ 334 stack frames between the first fib call and the next (see below).
>>
>> There seems to be some repetition going on. This might indicate some optimizations might be possible from within the org.codehaus.groovy.vmplugin.v7.IndyInterface.bootstrap code.
>
> reducing the trace quite a bit:
>
>>> at Fib.fib(Fib.groovy:-1)
>>> at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:212)
>>> at Fib.memoizedMethodPriv$fibBigInteger(Fib.groovy:3)
>>> at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:212)
>>> at Fib$_closure1.doCall(Fib.groovy:-1)
>>> at org.codehaus.groovy.runtime.memoize.Memoize$MemoizeFunction.call(Memoize.java:127)
>>> at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:212)
>>> at Fib.fib(Fib.groovy:-1)
>
> so fib calls dynamically into Memoize$MemoizeFunction.call, which will call (not with invokedynamic) Fib$_closure1.doCall, which dynamically calls Fib.memoizedMethodPriv$fibBigInteger, which makes the call to Fib.fib
>
> fib is a dummy for being able to call the fib method normally (for example from Java). memoizedMethodPriv$fibBigInteger is the real fib method, transformed for the purposes of memoization. Memoization here works by using a Closure only and no handle, since that is a non jdk7/8 exclusive version.
>
> Anyway... the situation could surely be improved by moving some code directly into the callsite for memoizedMethodPriv$fibBigInteger in fib. And that surely would reduce the problem.
>
Also perhaps there is a possibility in certain cases for optimizing the MH produced by each dynamic call, although i aint looked at the code for IndyInterface.selectMethod to see what might be possible.
> But the point is that this kind of solution is specialized to the current problem and my current fear is, that this kind of code will appear more often if a Groovy based system gets bigger. Is there a switch to set the "compile threshold for lambda forms"?
>
Yes, use the undocumented/unsupported system property:
java.lang.invoke.MethodHandle.COMPILE_THRESHOLD
See here:
http://hg.openjdk.java.net/jdk8/tl/jdk/file/tip/src/share/classes/java/lang/invoke/MethodHandleStatics.java
for that and other useful properties for analysing lambda forms.
Paul.
More information about the lambda-dev
mailing list