State of lambda forms stealing stack frames?
Andrew Haley
aph at redhat.com
Mon Jan 6 10:48:41 PST 2014
On 01/03/2014 12:35 PM, Andrew Haley wrote:
> On 01/03/2014 10:59 AM, Jochen Theodorou wrote:
>> notice, this is in Groovy, not Java and will require the indy enabled
>> version of Groovy to expose the described behaviour.
I've been looking at this. A word of warning: I'm not in the Oracle
HotSpot team, but I've been working on HotSpot for some time. So,
this is not authoritative but reasonably well-informed.
The stack trace that Java prints doesn't tell the whole story. I've
attached a snippet of the true stack trace at the point where the
stack overflows. It makes, er, interesting reading.
I think that wnat is happening is that you (and Groovy) are
unfortunate to be a victim of a design decision that was made a year
or so ago. Back then, invokedynamic was handled by a ton of
hard-to-maintain C++ code. The HotSpot team decide to throw much of
it away and generate bytecode instead, in the hope that the optimizer
would be able to "see through" all the invocations and smash it all
down to a single call in many cases. Generally speaking, this does
work. However, it can take a while before the optimizer kicks in, and
by this time your stack has already overflowed.
Having said all of that, the lambdas must be fairly amazing to require
such a lot of work. I don't know what fib$_closure1 looks like.
Note that this stack trace is just a small part of the whole stack.
This block repeats many times. It is the glue between
fib.this$4$memoizedMethodPriv$fibBigIntege and fib$_closure1.doCall.
I do not really understand why there are so many methods in the stack
trace. I can only guess that fib$_closure1 must be spectacularly
complex.
Andrew.
java.lang.invoke.DirectMethodHandle.internalMemberName(Ljava/lang/Object;)Ljava/lang/Object; : 0 ==> aload_0
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 1 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/6750210.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 25 ==> invokevirtual
java.lang.invoke.LambdaForm$NamedFunction.invoke_LLL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 30 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$NamedFunction.invoke_LL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 27 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$NamedFunction.invoke_LL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 27 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$NamedFunction.invoke_LL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 27 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$MH/1773283386.invokeExact_MT(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokehandle
java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L2(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 6 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/1826699684.invokeSpecial_LLL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 14 ==> invokestatic
java.lang.invoke.LambdaForm$DMH/889486595.invokeSpecial_LLLL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 16 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invoke_LLLL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 33 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$NamedFunction.invoke_LL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 27 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$DMH/1826699684.invokeSpecial_LLL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 14 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invoke_LLL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 30 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$DMH/1826699684.invokeSpecial_LLL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 14 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invoke_LLL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 30 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$DMH/1826699684.invokeSpecial_LLL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 14 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invoke_LLL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 30 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$DMH/1826699684.invokeSpecial_LLL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 14 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invoke_LLL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 30 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object; : 117 ==> invokevirtual
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$MH/1928931046.linkToCallSite(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokehandle
fib$_closure1.doCall(Ljava/math/BigInteger;)Ljava/lang/Object; : 2 ==> invokedynamic
native CodeBlob StubRoutines (1)
native <JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+1680>: 0xd0858b48
native <os::os_exception_wrapper(void (*)(JavaValue*, methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+50>:
native <JavaCalls::call(JavaValue*, methodHandle, JavaCallArguments*, Thread*)+124>:
native <Reflection::invoke(instanceKlassHandle, methodHandle, Handle, bool, objArrayHandle, BasicType, objArrayHandle, bool, Thread*)+3745>: 0x60858d48
native <Reflection::invoke_method(oopDesc*, Handle, objArrayHandle, Thread*)+517>:
native <JVM_InvokeMethod(JNIEnv*, jobject, jobject, jobjectArray)+733>:
native <Java_sun_reflect_NativeMethodAccessorImpl_invoke0+52>:
sun.reflect.NativeMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; : 100 ==> invokestatic
sun.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; : 6 ==> invokevirtual
java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; : 56 ==> invokeinterface
org.codehaus.groovy.reflection.CachedMethod.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; : 6 ==> invokevirtual
groovy.lang.MetaMethod.doMethodInvoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; : 9 ==> invokevirtual
org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(Ljava/lang/Class;Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;ZZ)Ljava/lang/Object; : 241 ==> invokevirtual
groovy.lang.MetaClassImpl.invokeMethod(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object; : 10 ==> invokevirtual
groovy.lang.Closure.call([Ljava/lang/Object;)Ljava/lang/Object; : 8 ==> invokeinterface
org.codehaus.groovy.runtime.memoize.Memoize$MemoizeFunction.call([Ljava/lang/Object;)Ljava/lang/Object; : 25 ==> invokevirtual
groovy.lang.Closure.call(Ljava/lang/Object;)Ljava/lang/Object; : 9 ==> invokevirtual
java.lang.invoke.LambdaForm$DMH/1008925772.invokeVirtual_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invoke_LL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 27 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
nmethod java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object;
java.lang.invoke.LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 67 ==> invokevirtual
java.lang.invoke.LambdaForm$LFI/815674463.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 21 ==> invokevirtual
java.lang.invoke.LambdaForm$NamedFunction.invoke_LL_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object; : 27 ==> invokehandle
java.lang.invoke.LambdaForm$DMH/349420578.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; : 11 ==> invokestatic
java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object; : 46 ==> invokehandle
nmethod java.lang.invoke.LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object;
More information about the lambda-dev
mailing list