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