-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
8268364: jmethod clearing should be done during unloading #4643
Conversation
👋 Welcome back coleenp! A progress list of the required criteria for merging this PR into |
Webrevs
|
Since this fix touches jmethodIDs, I think it would be a good idea to 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.
Just comments for now. I need to think about this more.
if (o == NULL || o == JNIMethodBlock::_free_method || !((Metadata*)o)->is_method()) { | ||
if (o == NULL || o == JNIMethodBlock::_free_method) { |
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 need to think more about deleting the is_method() check.
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 is_method() check was from when JNIHandleBlocks contained both jmethodID's and jobjects. It's a leftover from permgen elimination. I should have mentioned that in the PR comments. Now the only things that can be put in the JNIMethodBlocks are Methods, which the compiler type-checks, so that's the only thing that can come out (unless corrupted).
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 for the explanation.
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.
Still just comments because I'm not clear on the one code path.
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 did wonder if this was an issue but thought that if you are racingly using a jmethodid that is uncontrollably being unloaded (i.e. you are not holding the class alive in any way at all), then you are using the APIs in a seemingly buggy way that may or may not work the way you expect it to. Nevertheless, bugging out without a crash does seem better, and it did annoy me that these jmethodids are the only things unlinked that late.
Thanks for fixing this properly. This is the way I thought about fixing it, when I was not sure if it needed fixing or not. Sounds like it did need fixing after all.
@coleenp 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 24 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 |
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 for the explanation on the is_loader_alive()
part
and thanks for adding the new comment.
Thumbs up.
Thanks Dan for the careful review and questions. |
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.
Hi Coleen,
So IIUC by clearing during unload, rather than in the destructor, it ensures that a jmethodID seen as valid by Method::checked_resolve_jmethod_id
can't become invalid (due to a loader no longer being alive and being reclaimed) unless there is a safepoint (and assuming the JVM TI agent or application code, is not keeping the loader alive). So this fixes the situation in jvmti_GetMethodDeclaringClass
as per the bug report, but in general we would have to be careful in the JVM TI implementation to avoid safepoints after validating the jmethodID. Is that correct?
Thanks,
David
I'm not sure why the bot didn't put my reply to @dholmes-ora in the PR. |
Going to push as commit 3d84398.
Your commit was automatically rebased without conflicts. |
@coleenp - That was me that asked for the Tier[1-7]. Thanks for running that. |
Thanks for the suggestion, Dan! |
Mailing list message from Coleen Phillimore on hotspot-dev: On 7/1/21 12:38 PM, Erik ?sterlund wrote:
Erik, thank you for confirming my diagnosis of the problem and Thanks! |
Mailing list message from Coleen Phillimore on hotspot-dev: On 7/1/21 9:09 PM, David Holmes wrote:
Yes, it is true.? Once you have a Method*, you'd have to have a |
This patch moves the jmethod clearing to ClassLoaderData::unload() but also adds a check to Method::checked_resolved_jmethod_id() to handle the case where ZGC may be unloading a class but not have gotten to ClassLoaderData::unload() yet. JVMTI will read a NULL method for checked_resolved_jmethod_id() in this case, and not get a Method that will shortly, or has already been reclaimed in the Metaspace destructor.
Since I was there, I also added Method::is_valid_method() check to checked_resolve_jmethod_id. I don't think it's expensive anymore but it could be added under DEBUG. Either way method->method_holder()->is_loader_alive() will crash if !is_valid_method so we should leave it. As I wrote in the related issues, the bogus Method may have been because of a previous set of bugs with post_compiled_method_load events.
Tested with tiers 1-6 on linux-x64-debug and 1-3 on windows-x64-debug.
Also ran vmTestbase/nsk/{jdi,jvmti} tests with VM_OPTIONS=-XX:+UseZGC -XX:ZCollectionInterval=0.01 -XX:ZFragmen
tationLimit=0
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/4643/head:pull/4643
$ git checkout pull/4643
Update a local copy of the PR:
$ git checkout pull/4643
$ git pull https://git.openjdk.java.net/jdk pull/4643/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 4643
View PR using the GUI difftool:
$ git pr show -t 4643
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/4643.diff