Thanks for the clarification on this during the call today.
Summarizing for any observers:  The BSMs won't have run yet because the JVM would still be setting up the arguments prior to invoking the BSM.  
To resolve CP entry 10, we would need to
* resolve the static arguments to BSM1 (#1, #2, #11, #3)
* which for CP entry 11, would require resolving the static arguments to BSM2 (#4, #12, #5)
* which for CP entry 12, would require resolving the static arguments to BSM2 (#6, #10)
Which is the loop back to CP entry 10.
The stackoverflow in this example occurs in the static argument resolution phase, not the BSM invocation.  
BSMs that in use condy their implementation can result in side effects as expected when running user code.
----- Original message -----
From: Dan Smith <>
To: Daniel Heidinga <>
Subject: Re: Final CONSTANT_Dynamic spec
Date: Tue, Feb 13, 2018 6:55 PM
On Feb 12, 2018, at 10:05 PM, Daniel Heidinga <> wrote:
> That said, what side-effects are you concerned about? My claim is that re-resolution in this scenario would not, for example, trigger any class loading or bootstrap invocations.
The simplest implementation strategy for a resolution that is guaranteed to throw SOF is to re-execute it each time the constant needs to be re-resolved and let the SOF reoccur naturally.  This would result in new BSM invocations.
Nope, it shouldn't.
Constant pool:
#10 CONSTANT_Dynamic(BSM1, foo:I)
#11 CONSTANT_Dynamic(BSM2, bar:D)
#12 CONSTANT_Dynamic(BSM3, baz:J)
BSM1=invokestatic Bootstraps.m1(#1, #2, #11, #3)
BSM2=invokestatic Bootstraps.m2(#4, #12, #5)
BSM3=invokestatic Bootstraps.m3(#6, #10)
The spec says that, at the point where resolution of #10 is required by the program (e.g., an ldc), the following are resolved in order:
Then the recursion reaches #10, and a SOE occurs. Rather than throwing immediately, the implementation may choose to begin resolution of #10 again, which will trigger re-resolution of #1, #2, #4, and #6, but all of those have completed previously so they're just cache lookups.
None of the bootstrap methods m1, m2, or m3 would be invoked before the SOE, because we're still working on building an argument list. If #1, #2, #4, or #6 have bootstrap methods of their own, those would be invoked the first time and never again.
You might be thinking of a different case: a bootstrap method that triggers another call to itself within its own body. That's not addressed at all by this rule. The expected behavior falls out from the rules for bytecode evaluation: either there will be some control flow changes to break the cycle, or the stack will run out and you'll get a vanilla SOE.

Reply via email to