On Tue, 2 Dec 2025 10:30:46 GMT, Quan Anh Mai <[email protected]> wrote:
> Hi, > > This PR fixes the issue of the compiler crashing with "not enough operands > for reexecution". The issue here is that during > `Parse::catch_inline_exceptions`, the old stack is gone, and we cannot > reexecute the current bytecode anymore. However, there are some places where > we try to insert safepoints into the graph, such as if the handler is a > backward jump, or if one of the exceptions in the handlers is not loaded. > Since the `_reexecute` state of the current jvms is "undefined", it is > inferred automatically that it should reexecute for some bytecodes such as > `putfield`. The solution then is to explicitly set `_reexecute` to false. > > I can manage to write a unit test for the case of a backward handler, for the > other cases, since the exceptions that can be thrown for a bytecode that is > inferred to reexecute are `NullPointerException`, > `ArrayIndexOutOfBoundsException`, and `ArrayStoreException`. I find it hard > to construct such a test in which one of them is not loaded. > > Please kindly review, thanks a lot. It seems to be very difficult to force the back-edge safepoint to deoptimize. I tried creating a thread that calls System.gc(), but so far no crash. Still, I think the state is incorrect if reexecute=false. Setting reexecute to false means it will skip the current instruction. To correctly handle a deoptimization on the backwards branch, the debug state, bci, and exception location should match. I think we have 3 choices to prepare for maybe_add_safepoint(): 1. preserve stack inputs, use original bci, do not push exception oop, let interpreter reexecute and throw the exception (reexecute=true) This might be as simple as reversing the order of calls to push_ex_oop and maybe_add_safepoint. 2. trim stack, push exception object, use bci of exception handler (reexecute=true) This would require temporarily changing the bci for the maybe_add_safepoint call. 3. trim stack, throw exception (move to Thread) (reexecute=true) This requires extra unconditional overhead even though safepoint rarely happens. ------------- PR Comment: https://git.openjdk.org/jdk/pull/28597#issuecomment-3609883724
