-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8298099: [JVMCI] decouple libgraal from JVMCI module at runtime #11513
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 |
Webrevs
|
| } | ||
|
|
||
| // Returns true if jdk.internal.vm.ci is present on the file system. | ||
| bool ClassLoader::has_jvmci_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.
Would it be more useful to pass the module name so that the function tests if the module is is in the run-time image so that ClassLoader doesn't need to know the name "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.
Yes, good idea: 3e89d40253b70251f9a2facce4b1d8d69701c045
I also fixed a bug due in the size computation of path. Ideally, I'd factor out and re-use the same code in ClassLoader::add_to_exploded_build_list. However, the latter uses a ResourceMark which is not available when calling is_module_resolvable early in VM startup before JavaThread is initialized.
| static bool has_jvmci_module(); | ||
|
|
||
| // Determines if the `module_name` module is resolvable. | ||
| static bool is_module_resolvable(const char* module_name); |
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.
Is "resolvable" the right concept here? Or should it be something like "findable" instead?
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 --limit-modules isn't used, it is testing if the module is "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 assume this function should therefore be named 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.
How about this:
// Determines if the named module is present in the
// modules jimage file or in the exploded modules directory.
static bool is_module_observable(const char* module_name);
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.
That looks okay to me. I don't have any other comments on this part.
dholmes-ora
left a comment
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.
Sorry Doug not a full review (not familiar enough with code) but a few drive-by nits.
Thanks.
src/hotspot/share/jvmci/jvmci.cpp
Outdated
| if (thread != nullptr && thread->is_Java_thread()) { | ||
| ResourceMark rm; | ||
| tty->print("JVMCITrace-%d[%s]:%*c", level, thread->name(), level, ' '); | ||
| JavaThreadState state = ((JavaThread*) thread)->thread_state(); |
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.
Please use JavaThread::cast(thread)
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 made this change. Out of interest, I grep'ed through src/hotspot and found a few other instances of (JavaThread*) style casts. While most of these are probably older code, I'm wondering what the guidelines are in this area. I assume JavaThread::cast should be preferred always given the assertion checking it does?
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.
Yes JavaThread::cast(t) is preferred. We did a lot of cleanup work ensuring we use JavaThread when always dealing with a JavaThread, and so reduce the places we need to cast. I'm a little surprised we still have some raw casts left as I thought we had cleaned them all up. I will check and file another cleanup RFE. Thanks.
src/hotspot/share/jvmci/jvmci.cpp
Outdated
| Thread* thread = Thread::current_or_null_safe(); | ||
| if (thread != nullptr) { | ||
| if (thread != nullptr && thread->is_Java_thread()) { | ||
| ResourceMark rm; |
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 can pass thread to the rm constructor to save an internal lookup.
src/hotspot/share/jvmci/jvmci.cpp
Outdated
| // According to check_access_thread_state, it's unsafe to | ||
| // resolve the j.l.Thread object unless the thread is in | ||
| // one of the states above. | ||
| tty->print("JVMCITrace-%d[%s@" INTPTR_FORMAT "]:%*c", level, thread->type_name(), p2i(thread), level, ' '); |
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 the current preferred style is to use PTR_FORMAT here.
| @@ -1,10 +1,12 @@ | |||
| /* | |||
| * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. | |||
| * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. | |||
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 just moved the file the original copyright year should remain - this is not new code.
| if (!create_numbered_module_property("jdk.module.addmods", "jdk.internal.vm.ci", addmods_count++)) { | ||
| return false; | ||
| if (ClassLoader::is_module_observable("jdk.internal.vm.ci")) { | ||
| if(!create_numbered_module_property("jdk.module.addmods", "jdk.internal.vm.ci", addmods_count++)) { |
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.
Nit: space after if please
| * Support for translating exceptions between the HotSpot heap and libjvmci heap. | ||
| */ | ||
| @SuppressWarnings("serial") | ||
| final class TranslatedException extends Exception { |
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.
Would it be possible to re-format this to avoid the wildly long (150+) lines? This seems to be moving jdk.vm.ci.hotspot.TranslatedException and hard to see what is going on.
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.
Is there some tool support for formatting Java source code to meet OpenJDK coding guidelines? Rather unfortunate that one has to do this manually and reviewers have to spend time manually checking it.
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 isn't globally agreed code conventions. The cleanup in the latest version looks okay.
| * only contains String keys and values. | ||
| */ | ||
| private static byte[] serializePropertiesToByteArray(Properties p) throws IOException { | ||
| private static byte[] serializePropertiesToByteArray(Properties p, boolean filter) throws IOException { |
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 we need more context as to why there are non-String system properties in use here.
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 parameter exists to allow a caller to pass in a Properties object that is guaranteed to have only String keys and so does not need the extra filtering done in this method. I'll refactor the code to make it clearer.
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.
Hopefully this makes it clearer: 5c61079
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.
Thanks. I initially assumed it was done to support non-String key/values but it's actually an optimization because the save properties are always Strings.
| props.put(e.getKey(), e.getValue()); | ||
| } | ||
| if (props.get("oome") != null) { | ||
| throw new OutOfMemoryError("forced OOME"); |
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 don't think code in java.base should be checking for a property named "oome". Is this for a test that sets this system property on the command line?
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.
Sorry, that's debug code that I will remove.
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.
Thanks, I couldn't see it set as a property anywhere so didn't know why it was there. I don't have any comments on this area.
|
@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 no new commits pushed to the ➡️ To integrate this PR with the above commit message to the |
| private static Throwable create(String className, String message, Throwable cause) { | ||
| // Try create with reflection first. | ||
| try { | ||
| Class<?> cls = Class.forName(className); |
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.
A question about the Class.forName usage here. Class.forName uses the defining class loader of the current class so I'm wondering if the exceptions to be decoded are always of a type defined to the boot loader? jdk.internal.vm.ci is defined to the boot loader so this code hasn't really changed, it's just "new" to java.base in this PR.
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 exceptions can be of any type and defined by any loader. In the case that Class.forName fails, the name of the original exception type is shown as part of TranslationException.toString(). Combined with the stack trace, this has always been sufficient to understand the origin of an exception thrown on a HotSpot/libjvmci mixed stack.
|
/integrate |
|
Going to push as commit 8b69a2e.
Your commit was automatically rebased without conflicts. |
|
@dougxc Two reviews are needed for all non-trivial hotspot changes, and this also warranted a review from core-libs! Your discussions with Alan still seemed to be in-progress. |
|
Sorry I checked with Alan over Slack who said to go ahead with merging. |
Yeah, I was busy at the time and didn't get a chance to say that I didn't have any more comments/issues. |
Libgraal is compiled ahead of time and should not need any JVMCI Java code to be dynamically loaded at runtime. Prior to this PR, this is not the case due to:
jdk.vm.ci.services.Services.initializeSavedProperties(byte[])andjdk.vm.ci.services.Services.serializeSavedProperties(). This code should be moved tojava.base/jdk.internal.vm.VMSupport.jdk.internal.vm.ci//jdk.vm.ci.hotspot.TranslatedExceptiontojava.base/jdk.internal.vm.VMSupport.This PR makes the above changes. As a result, it's possible to build a JDK image that includes (and uses) libgraal but does not include
jdk.internal.vm.ciorjdk.internal.vm.compiler. This both reduces footprint and better isolates the JVMCI and the Graal compiler as accessing these components from Java code is now impossible.Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/11513/head:pull/11513$ git checkout pull/11513Update a local copy of the PR:
$ git checkout pull/11513$ git pull https://git.openjdk.org/jdk pull/11513/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 11513View PR using the GUI difftool:
$ git pr show -t 11513Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/11513.diff