-
Notifications
You must be signed in to change notification settings - Fork 5.8k
8345826: Do not automatically resolve jdk.internal.vm.ci when libgraal is used #25240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back dnsimon! A progress list of the required criteria for merging this PR into |
@dougxc This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 226 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
I found your explanation quite confusing, but the bug title is actually the most clear description of the fix. Basically libjvmci doesn't require the existence of jdk.internal.vm.ci on the HotSpot side since it has effectively compiled that into itself. So we are decoupling the ability to use JVMCI from the presence of the JVMCI module. A short comment along these lines in at least your changes in check_vm_args_consistency would be helpful I think. I do find it confusing that we are explicitly passing |
I added the requested comment and tried to clarify the PR description. Let me know if clarification is needed.
Without that option, the module will be missing and without the fail-fast check in
|
Webrevs
|
That should be in PR and RFE (JBS) Descriptions! This was my main question about filed REF. |
// compiled into the libjvmci image itself. Without libjvmci, there | ||
// is no other representation of the jdk.internal.vm.ci module | ||
// so it needs to be added to the root module set. | ||
if (ClassLoader::is_module_observable("jdk.internal.vm.ci") && !UseJVMCINativeLibrary && !_jvmci_module_added) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case ClassLoader::is_module_observable("jdk.internal.vm.ci")
== true
when _jvmci_module_added
== false
?
I assume this code is executed after check command line for --add-modules=jdk.internal.vm.ci
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation for is_module_observable
is:
// Determines if the named module is present in the
// modules jimage file or in the exploded modules directory.
That is, is the module present on disk. On the other hand, _jvmci_module_added
is a test of whether an --add-modules
option has been seen whose value included jdk.internal.vm.ci
.
I've updated both the PR and JBS issue descriptions. Let me know if either still need improvement. |
if (ClassLoader::is_module_observable("jdk.internal.vm.ci") && !UseJVMCINativeLibrary && !_jvmci_module_added) { | ||
jio_fprintf(defaultStream::error_stream(), | ||
"'+EnableJVMCI' requires '--add-modules=jdk.internal.vm.ci' when UseJVMCINativeLibrary is false\n"); | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's something a bit uncomfortable about an error message naming a JDK internal module to specify to --add-modules.
If I understand correctly, +EnableJVMCI and libgraal is all good, the set of modules in the training run is the same as the production run. However, in the no libgraal scenario, and a mismatch between training and production runs (is that right)? then AOT is disabled. Is it really terrible to disable the AOTClassLinking optimizations in that scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the set of modules in the training run is the same as the production run
I don't think that's true. That is, I don't think +EnableJVMCI is used in the training run is it @iklam ?
Is it really terrible to disable the AOTClassLinking optimizations in that scenario?
Depends if you care as much about VM startup when using libgraal as when using C2. Is there a reason why only one of these should have AOTClassLinking startup benefits?
There's also the issue of all the AOTClassLinking tests having to be disabled/ignored/problem listed in the libgraal mach5 tiers. This is what initially motivated @iklam and I to come up with this solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depends if you care as much about VM startup when using libgraal as when using C2. Is there a reason why only one of these should have AOTClassLinking startup benefits?
I should have been clearer, my question/comment was about the no-libgraal case, not the libgraal case. With the proposed change, I think you are looking to print an error. I'm wondering why it can't continue to add jdk.internal.vm.ci to the set of root modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, that's a good suggestion. I'll explore further.
And I now understand your first comment about "+EnableJVMCI and libgraal is all good" is in the context of having applied this PR. In that context, the set of modules in the training run is indeed the same as the production run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pushed a commit that implements your suggestion and reduces the size of the overall change nicely. More importantly, I think it's a better design - thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this latest version!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran a recent build of Oracle JDK 25 that has libjvmcicompiler.so (not including your changes):
$ ./bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseGraalJIT -XX:+PrintFlagsFinal --version | \
egrep '(EnableJVMCI)|(UseJVMCICompiler)|(UseJVMCINativeLibrary)'
bool EnableJVMCI = true {JVMCI product} {default}
bool EnableJVMCIProduct = true {JVMCI product} {command line}
bool UseJVMCICompiler = true {JVMCI product} {default}
bool UseJVMCINativeLibrary = true {JVMCI product} {default}
$ ./bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+PrintFlagsFinal --version | \
egrep '(EnableJVMCI)|(UseJVMCICompiler)|(UseJVMCINativeLibrary)'
bool EnableJVMCI = true {JVMCI experimental} {command line}
bool EnableJVMCIProduct = false {JVMCI experimental} {default}
bool UseJVMCICompiler = false {JVMCI experimental} {default}
bool UseJVMCINativeLibrary = true {JVMCI experimental} {default}
So If you specify only -XX:+EnableJVMCI
in the command-line, UseJVMCINativeLibrary
will be true. As a result, with your latest version, the jdk.internal.vm.ci
module is not added.
If you have an app that wants to use the jdk.internal.vm.ci API, you must specify both -XX:+EnableJVMCI
and --add-modules=jdk.internal.vm.ci
. Is this intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you have an app that wants to use the jdk.internal.vm.ci API, you must specify both -XX:+EnableJVMCI and --add-modules=jdk.internal.vm.ci.
You should only have to specify --add-modules=jdk.internal.vm.ci
and that now sets +EnableJVMCI
. If you also want libgraal to be used as the JIT (instead of C2), then you need to add -XX:+UseGraalJIT
.
For the Truffle on Oracle JDK, this means:
--add-modules=jdk.internal.vm.ci
: Use C2 for JIT ("hosted") compilation and libgraal for Truffle ("guest") compilation--add-modules=jdk.internal.vm.ci -XX:+UseGraalJIT
: Use libgraal for both JIT and Truffle compilation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I forgot the setting on EnableJVMCI to true. Thanks for the explanation.
PropertyList_unique_add(&_system_properties, "jdk.internal.vm.ci.enabled", "true", | ||
AddProperty, UnwriteableProperty, InternalProperty); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of the jdk.internal.vm.ci.enabled
property? Should it be enabled only if the jdk.internal.vm.ci
module is added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It exists to check in various Java-level entry points that the JVMCI VM support has been enabled so a nicer error message can be thrown that provides a possible corrective action. However, since it's now impossible to load the JVMCI module without enabling the JVMCI VM support, this is no longer of any use. I'll remove it.
While testing this out on Graal, I discovered an interesting corner case.
If the JVMCI module is indirectly added to the root module set, it results in an error:
That is, if an app wants to use the JVMCI module, it needs to explicitly communicate this to the launcher. By the time the root module graph is being initialized in ModuleBootstrap, it's too late to set I improved the error message to make this clear:
|
@@ -35,6 +35,8 @@ | |||
#include "gc/g1/g1CardTable.hpp" | |||
#endif // INCLUDE_G1GC | |||
|
|||
#define JAVA_NOT_ENABLED_ERROR_MESSAGE "JVMCI is not enabled. Must specify '--add-modules=jdk.internal.vm.ci' or '-XX:+EnableJVMCI' to the java launcher." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You meant JVMCI_NOT_ENABLED_ERROR_MESSAGE
I assume?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You meant
JVMCI_NOT_ENABLED_ERROR_MESSAGE
I assume?
Ha! Nice catch ;-)
@@ -170,6 +170,7 @@ public void jniEnomemTest() throws Exception { | |||
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( | |||
"-XX:+UnlockExperimentalVMOptions", | |||
"-XX:+EnableJVMCI", | |||
"--add-modules=jdk.internal.vm.ci", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stared at this for a while to understand why passing this option was required. It's a bit confusing that explicitly passing -XX:+EnableJVMCI
has different effects based on the value of UseJVMCINativeLibrary. I think that if EnableJVMCI
is passed on the command line then it should add the module even if libgraal is in use. So something like:
if ((!UseJVMCINativeLibrary || FLAG_IS_CMDLINE(EnableJVMCI) && ClassLoader::is_module_observable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not aware FLAG_IS_CMDLINE can be used for altering the semantics of a flag but there seems to be at least one precedent for it with UseCompactObjectHeaders. This is quite nice as now nothing needs to change for Truffle users in terms of enabling the Truffle optimized runtime (cc @chumer).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new version seems nice and clean.
Any further feedback or concerns @iklam or @AlanBateman ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Latest version looks good to me.
In addition to loading the JVMCI module when |
_jvmci_module_added = true; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only works if jdk.internal.vm.ci is specified to --add-modules, it won't set _jvmci_module_added if jdk.internal.vm.ci is resolved because some other module require it. As the module is JDK internal and doesn't export an API then I assume it would be rare-to-never to require it, is that right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. I realized this might be a bit confusing so improved the error message a little: #25240 (comment)
But as you say, it should never be encountered in practice.
@@ -35,6 +35,8 @@ | |||
#include "gc/g1/g1CardTable.hpp" | |||
#endif // INCLUDE_G1GC | |||
|
|||
#define JVMCI_NOT_ENABLED_ERROR_MESSAGE "JVMCI is not enabled. Must specify '--add-modules=jdk.internal.vm.ci' or '-XX:+EnableJVMCI' to the java launcher." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the exception message for an InternalError so maybe this is okay but in general I don't think you want to be asking users to have to name a JDK internal module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think anyone using a non-standard configuration for Graal would not be surprised about JVMCI and would actually appreciate the extra hint when they get things "wrong".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming we want users to use -XX:+EnableJVMCI
over --add-modules=jdk.internal.vm.ci
for said reason, maybe flip the order?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
Thanks for the reviews. /integrate |
Going to push as commit 8153683.
Your commit was automatically rebased without conflicts. |
The
EnableJVMCI
flag currently serves 2 purposes:jdk.internal.vm.ci
to the root module set.This PR changes nothing about the first point.
On the second point, to use the
jdk.internal.vm.ci
module when libgraal is enabled,-XX:+EnableJVMCI
must be explicitly specified to the launcher (as opposed to being true as a result of-XX:+UseJVMCICompiler
or-XX:+EnableJVMCIProduct
). Alternatively,--add-modules=jdk.internal.vm.ci
can be specified - it has the same semantics as-XX:+EnableJVMCI
.If libgraal is not enabled, +EnableJVMCI will continue to add
jdk.internal.vm.ci
to the root module set.The primary motivation is to make use of libgraal compatible with
-XX:+AOTClassLinking
. This flag relies on the root module set archive created in a training run. If the root module set is different in the production run, the AOTClassLinking optimizations are disabled. Asjdk.internal.vm.ci
is not resolved in the training run, it must not be resolved in production run. As such,-XX:+EnableJVMCI
must not cause resolution ofjdk.internal.vm.ci
, otherwise libgraal will not have the startup advantages of AOTClassLinking.Graal adaption PR: oracle/graal#11212
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/25240/head:pull/25240
$ git checkout pull/25240
Update a local copy of the PR:
$ git checkout pull/25240
$ git pull https://git.openjdk.org/jdk.git pull/25240/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 25240
View PR using the GUI difftool:
$ git pr show -t 25240
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/25240.diff
Using Webrev
Link to Webrev Comment