JvmtiThreadState::cur_stack_depth() contains the following
// heavy weight assert
assert(_cur_stack_depth == count_frames(),
"cur_stack_depth out of sync");
}
When doing a single step over a line of code, this assert code is executed on every method entry and exit in the thread. The count_frames() call is rather expensive. With a slowdebug build I was noticing a particular stepover taking 8 seconds with a slowdebug build, about 3 with a regular debug build, and no delay with a product/release build. This was the code being stepped over:
URL url = URI.create("http://openjdk.java.net/").toURL();
try (InputStream in = url.openStream()) {
in.readAllBytes();
}
It was the url.openStream() call that was particularly slow. I tracked down the slowness to the above assert, and removing it makes the stepover complete in under a second even with a slow debug build.
url.openStream() does a large number of method calls, resulting in executing this assert a very large number of times. It does so on every method entry and exit. This is because the debug agent does a NotifyFramePop on the thread when doing a stepover, which keeps the thread in interp mode, which results in callbacks into JVMTI for every method entry and exit, both of which cause the assert to be executed.
// heavy weight assert
assert(_cur_stack_depth == count_frames(),
"cur_stack_depth out of sync");
}
When doing a single step over a line of code, this assert code is executed on every method entry and exit in the thread. The count_frames() call is rather expensive. With a slowdebug build I was noticing a particular stepover taking 8 seconds with a slowdebug build, about 3 with a regular debug build, and no delay with a product/release build. This was the code being stepped over:
URL url = URI.create("http://openjdk.java.net/").toURL();
try (InputStream in = url.openStream()) {
in.readAllBytes();
}
It was the url.openStream() call that was particularly slow. I tracked down the slowness to the above assert, and removing it makes the stepover complete in under a second even with a slow debug build.
url.openStream() does a large number of method calls, resulting in executing this assert a very large number of times. It does so on every method entry and exit. This is because the debug agent does a NotifyFramePop on the thread when doing a stepover, which keeps the thread in interp mode, which results in callbacks into JVMTI for every method entry and exit, both of which cause the assert to be executed.