On Fri, 22 May 2026 09:47:16 GMT, Serguei Spitsyn <[email protected]> wrote:
>> This change fixes a long standing performance issue related to the debugger >> single stepping that is using JVMTI `FramePop` events as a part of step over >> handling. The performance issue is that the target thread continues its >> execution in very slow `interp-only` mode in a context of frame marked for >> `FramePop` notification with the JVMTI `NotifyFramePop`. It includes other >> method calls recursively upon a return from the frame. >> >> This fix is to avoid enforcing the `interp-only` execution mode for threads >> when `FramePop` events are enabled with the JVMTI >> `SetEventNotificationMode()`. Instead, the target frame has been deoptimized >> and kept interpreted by disabling `OSR` optimization by the function >> `InterpreterRuntime::frequency_counter_overflow_inner()`. (Big thanks to >> @fisk for this suggestion!) Additionally, some tweaks are applied in several >> places where the `java_thread->is_interp_only_mode()` is checked. >> The other details will be provided in the first PR request comment. >> >> Testing: >> - test `serviceability/jvmti/vthread/ThreadStateTest` was updated to >> provide some extra test coverage >> - submitted mach5 tiers 1-6 >> >> - [x] I confirm that I make this contribution in accordance with the >> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai). > > Serguei Spitsyn has updated the pull request incrementally with one > additional commit since the last revision: > > review: 1. Add asserts, rem comment 2. Remove can_generate_frame_pop_events > from can_generate_interpreter_events This is expected. In the [IDEA-292196](https://youtrack.jetbrains.com/issue/IDEA-292196) example the debugger is going to single step into foo(). Once in foo() it will turn off single stepping and do a NotifyFramePop on foo(). The FramePop is the signal to enable single stepping again, so for most of this test runs with single stepping disabled. However, the NotifyFramePop on foo() forces foo() to be interpreted, which is why it runs slow. Thsi PR does not get rid of the requirement that NotifyFramePop be interpreted. The fix is that the whole thread no longer has to be interpreted, ust the NotifyFramePop frame. You do see a bit of a speedup though since increment() is compiled. In the 2nd example given above, foo() just calls foo2(), which is where all the work is done. So foo() is interpreted, but foo2() can be compiled. Since all the work is done in foo2(), it runs in 3ms. ------------- PR Comment: https://git.openjdk.org/jdk/pull/28407#issuecomment-4905795215
