[crac] RFR: 8376959: [CRaC] Turn simengine into shared library [v2]
Timofei Pushkin
tpushkin at openjdk.org
Tue Feb 3 14:06:37 UTC 2026
On Tue, 3 Feb 2026 09:37:34 GMT, Radim Vansa <rvansa at openjdk.org> wrote:
>> Right now `simengine` is implemented as an executable, invoked through `libcrexec` that implements the C/R API. Since the programmatic C/R API should be the main interface, any exec API is redundant; let's turn `simengine` into shared (dynamic) library implementing the API on its own.
>>
>> The `pauseengine` does not need to exist on its own; this can be only an option `pause=true` for `simengine`. The implementation is Linux only (and it is out of scope to fill in a non-Linux implementation - the `pause` option can be just excluded in non-Linux `libsimengine`).
>>
>> We expect to turn `libcrexec` + `criuengine` into `libcriuengine` in a follow up (not as part of this issue).
>
> Radim Vansa has updated the pull request incrementally with one additional commit since the last revision:
>
> Implement static build & other platforms
src/hotspot/share/runtime/crac_engine.cpp line 69:
> 67: }
> 68:
> 69: static bool find_engine(const char *dll_dir, char *path, size_t path_size, bool *is_library, char *resolved_engine, size_t resolved_engine_size) {
This is becoming so complex... With the planned removal of `crexec` it should become simpler but I wonder if we can also simplify it also by deprecating the ability to use both `nameengine` and `name`: allow only `name` that must map to `nameengine.so`? Can be done in a separate PR.
src/hotspot/share/runtime/crac_engine.cpp line 113:
> 111: }
> 112:
> 113: if (is_pauseengine()) {
Ideally on Mac `pauseengine` should not be treated specially to preserve the old behavior
src/hotspot/share/runtime/crac_engine.cpp line 116:
> 114: assert(sizeof(SIMENGINE) <= resolved_engine_size, "must be");
> 115: memcpy(resolved_engine, SIMENGINE, sizeof(SIMENGINE));
> 116: log_warning(crac)("-XX:CRaCEngine=pause/pauseengine is deprecated; use -XX:CRaCEngine=simengine -XX:CRaCEngineOptions=pause=true");
Let's define an obsoletion/expiration version for this. I suggest 28 for both obsoletion and expiration: this way for LTS releases it will be deprecated in April 2026 and obsoleted+expired in April 2027.
Suggestion:
assert(JDK_Version::current().compare(JDK_Version::jdk(28)) < 0, "pauseengine handling must be removed as obsolete");
if (is_pauseengine()) {
assert(sizeof(SIMENGINE) <= resolved_engine_size, "must be");
memcpy(resolved_engine, SIMENGINE, sizeof(SIMENGINE));
log_warning(crac)("Option '-XX:CRaCEngine=pauseengine' was deprecated in version 27 and will be removed in version 28. Use options '-XX:CRaCEngine=simengine -XX:CRaCEngineOptions=pause=true' instead.");
src/hotspot/share/runtime/crac_engine.cpp line 117:
> 115: memcpy(resolved_engine, SIMENGINE, sizeof(SIMENGINE));
> 116: log_warning(crac)("-XX:CRaCEngine=pause/pauseengine is deprecated; use -XX:CRaCEngine=simengine -XX:CRaCEngineOptions=pause=true");
> 117: } else if (static_cast<size_t>(os::snprintf(resolved_engine, resolved_engine_size, "%s", CRaCEngine)) >= resolved_engine_size) {
We could move `path_len = strlen(CRaCEngine)` at the very beginning of this function from under if, use it here for the check and use `memcpy` in case of success instead.
src/hotspot/share/runtime/crac_engine.cpp line 340:
> 338: if (!find_engine(dll_dir, path, sizeof(path), &is_library,
> 339: resolved_engine_func + sizeof(CRLIB_API_FUNC), MAX_ENGINE_LENGTH)) {
> 340: log_error(crac)("Cannot find CRaC engine %s", CRaCEngine);
Suggestion:
if (!find_engine(dll_dir, path, sizeof(path), &is_library,
resolved_engine_func + sizeof(CRLIB_API_FUNC), MAX_ENGINE_LENGTH)) {
log_error(crac)("Cannot find CRaC engine %s", CRaCEngine);
src/java.base/share/native/libcrcommon/crcommon.hpp line 28:
> 26: #define CRCOMMON_HPP
> 27:
> 28: #include <stdio.h>
Suggestion:
#include <cstdio>
src/java.base/share/native/libcrcommon/crcommon.hpp line 74:
> 72: void *_image_constraints;
> 73: void *_image_score;
> 74: };
Since this is not exposed to C, can't this have the actual classes as field types? Also the fields are not private/protected so no underscores should be used.
Actually, since all users of this is also C++ code compiled by the same compiler, isn't it possible to omit the C API layer of `crcommon`?
src/java.base/share/native/libcrexec/environment.hpp line 2:
> 1: /*
> 2: * Copyright (c) 2025,2026, Azul Systems, Inc. All rights reserved.
Suggestion:
* Copyright (c) 2025, 2026, Azul Systems, Inc. All rights reserved.
src/java.base/share/native/libsimengine/simengine.cpp line 86:
> 84:
> 85: static crlib_conf_t* create_simengine() {
> 86: SimEngine *engine = new(std::nothrow) SimEngine();
Neither `init_conf` nor `SimEngine` constructor report any errors — how are the code and the user supposed to know if something goes wrong there?
-------------
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2758721973
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2759015075
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2758659955
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2758674949
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2758734889
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2758838422
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2759025361
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2758952911
PR Review Comment: https://git.openjdk.org/crac/pull/289#discussion_r2758813224
More information about the crac-dev
mailing list