JIT compilers in current Hotspot are compiling the code while being in native state. So if there is a running compilation, it does not block shutdown naturally. The shutdown code has cooperative mechanism to coordinate shutdown of compiler threads. Shutdown code sets the `CompilerBroker::should_block`, and compilers are regularly checking it with `CompilerBroker::maybe_block`. When shutdown is pending, the running compiler threads would eventually hit that maybe_block, block at transition to VM state, and that would allow shutdown to proceed.
The promptness of this mechanism depends on Compiler checking for blocking requests regularly. Currently, C2 checks this at the beginning of each Phase and sometimes during EA connection graph construction. C1 does not do these checks at all. Attached patch makes it obvious we still have significant time between these checks in many workloads:
$ CONF=linux-x86_64-server-release make images test TEST=compiler/loopopts/superword/
Standard Output
---------------
TestVM main() called - about to run tests in class compiler.loopopts.superword.TestSplitPacks
For random generator using seed: -158124895714017129
To re-run test with same seed value please add "-Djdk.test.lib.random.seed=-158124895714017129" to command line.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (compileBroker.cpp:2079), pid=2044819, tid=2044909
# fatal error: Last block check was 103 ms ago
#
# JRE version: OpenJDK Runtime Environment (25.0) (build 25-internal-adhoc.shade.jdk)
# Java VM: OpenJDK 64-Bit Server VM (25-internal-adhoc.shade.jdk, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x6daaf3] CompileBroker::maybe_block()+0x123
This realistically only becomes a problem when we have a long-running compilation at shutdown time. I have some weak evidence this affects run-to-run variance on Leyden performance tests.
It would be good to investigate if we can sprinkle more of these checks around compiler code where it makes sense, without sacrificing compiler performance. For example, should we also check at ~Phase? Should we check near Compile::print_method? Somewhere else? This needs deeper investigation.
The promptness of this mechanism depends on Compiler checking for blocking requests regularly. Currently, C2 checks this at the beginning of each Phase and sometimes during EA connection graph construction. C1 does not do these checks at all. Attached patch makes it obvious we still have significant time between these checks in many workloads:
$ CONF=linux-x86_64-server-release make images test TEST=compiler/loopopts/superword/
Standard Output
---------------
TestVM main() called - about to run tests in class compiler.loopopts.superword.TestSplitPacks
For random generator using seed: -158124895714017129
To re-run test with same seed value please add "-Djdk.test.lib.random.seed=-158124895714017129" to command line.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (compileBroker.cpp:2079), pid=2044819, tid=2044909
# fatal error: Last block check was 103 ms ago
#
# JRE version: OpenJDK Runtime Environment (25.0) (build 25-internal-adhoc.shade.jdk)
# Java VM: OpenJDK 64-Bit Server VM (25-internal-adhoc.shade.jdk, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x6daaf3] CompileBroker::maybe_block()+0x123
This realistically only becomes a problem when we have a long-running compilation at shutdown time. I have some weak evidence this affects run-to-run variance on Leyden performance tests.
It would be good to investigate if we can sprinkle more of these checks around compiler code where it makes sense, without sacrificing compiler performance. For example, should we also check at ~Phase? Should we check near Compile::print_method? Somewhere else? This needs deeper investigation.
- relates to
-
JDK-8349927 Waiting for compiler termination delays shutdown for 10+ ms
-
- Resolved
-