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

It seems that the first frame is still interpreted (i.e., `foo()`). And inner 
frames aren't. The following sample demonstrates it:

class test {
  public static void main(String[] args) {
    int x = foo();
    System.out.println(x);
  }

  static int foo() {
      return foo2();
  }

  static int foo2() {
    long start = System.currentTimeMillis();
    int a = 1;
    for (int i = 0; i < 100_000_000; i++) {
      a = increment(a);
    }
    System.out.println("It took " + (System.currentTimeMillis() - start) + 
"ms");
    return a;
  }

  private static int increment(int a) {
    return a + 1;
  }
}

jdb runs fast now:

Breakpoint hit: "thread=main", test.main(), line=3 bci=0
3        int x = foo();

main[1] next
> It took 3ms

-------------

PR Comment: https://git.openjdk.org/jdk/pull/28407#issuecomment-4845862823

Reply via email to