-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
8330253: Remove verify_consistent_lock_order #18782
Conversation
👋 Welcome back aboldtch! A progress list of the required criteria for merging this PR into |
@xmas92 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 44 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 |
Webrevs
|
Can you describe the transitional state this fix avoids, and why it only needs to deal with monitorenter from a synchronized method prologue, and not also monitorenter from synchronized blocks. |
Nevermind, I see that it does handle monitorenter for synchronized methods. |
// If deoptimizing from monitorenter bytecode we maybe in transitional state. Skip verification. | ||
if (!is_syncronized_entry && bc != Bytecodes::Code::_monitorenter) { | ||
deoptee_thread->lock_stack().verify_consistent_lock_order(lock_order, exec_mode != Deoptimization::Unpack_none); | ||
} |
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 above checks would also hit the follow false positives:
- deopt in counter overflow in prologue, not in monitorenter
- monitorenter at bci 0 when raw_bci is -1 (assuming it got past the verifier)
but seems mostly harmless to skip checks in those cases.
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 thought the original check was fine. Could you elaborate on these 2 cases, I didn't really get them.
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.
Deoptimization is already expensive, and this edge case is rare, so I think it would be better to compute the actual previous bytecode here, and not use bci - 1.
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.
Other debug checks in deoptimization compute oop maps, which have to iterate all the bytecodes, so doing it here also wouldn't be so bad. Or how about not checking bytecodes and instead checking a flag on JavaThread that says we are in monitor enter native code?
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.
Deoptimization is already expensive, and this edge case is rare, so I think it would be better to compute the actual previous bytecode here, and not use bci - 1.
Alright I will give that a go then, unless we think the second option is more appropriate.
Or how about not checking bytecodes and instead checking a flag on JavaThread that says we are in monitor enter native code?
What state would that be? Any current state we setup is after transitioning to VM which seems to late. I guess it would be possible to instrument SharedRuntime::monitor_enter_helper
with some thread local state we can check. But the interpreter has its own entry point. But I guess we would never reach this point for the interpreter, as there is no such thing as deoptimizing or unpacking interpreted frames.
What is the feeling here? What would be more appropriate? Adding some thread local debug state that we set before transitioning to VM in SharedRuntime::monitor_enter_helper
seems like the most precise solution, but we need to be sure that there are no earlier safepoint polls before this point within the execution of the monitorenter bytecode.
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 see there is _pending_monitorenter
but this would only handle synchronized method entry.
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 the idea of a flag better, because it is foolproof. Why can't we set it in ObjectSynchronizer::enter? I don't think it matters if there is a safepoint check before that, because the lock stack is still consistent at that point.
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.
(Currently) the lock stack is always consistent at safepoints w.r.t. what is actually locked. However the lock stack may not be consistent with the most recent lock returned by the leaf compiledVFrame::monitors()
.
But you are correct that it can probably be moved to ObjectSynchronizer::enter
there are no safepoint polls between SharedRuntime::monitor_enter_helper
and that point. Similarly there are no safepoints polls in the runtime until after set_current_pending_monitor
is called.
So with these following assumptions.
- LockStack is consistent at safepoints w.r.t. locked monitors
- No safepoint polls exist from the point that compiledVFrame::monitors() starts returning the monitorinfo for the currently executing monitorenter until either it calls into the runtime or finishes locking.
I do not believe 1. is likely to ever change. But I have limited understanding of the validity of 2. nor if it something that can change.
If both these assumptions are correct than simply skipping the verification when deoptee_thread->current_pending_monitor() != nullptr
would suffice.
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 believe those assumptions will always hold, but per separate discussions, let's go with what you have.
Please clarify what pre-integration testing is being done. As far as I can |
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.
Thumbs up on the changes themselves.
Unless I missed it, I haven't seen updated info on the pre-integration testing
in general and specifically about whether Tier8 was executed.
I was playing with a reproducer, maybe it would be good to add it: pchilano@77a85a0 |
Just finished Tier8. Also stress tested the reproducer (both @pchilano and the reproducers from Tier8)
Great thanks, I'll add it. /contributor add @pchilano |
@xmas92 |
There were some additional issues with 10d70ea that has to be resolved before this could go in. And multiple engineers in this area agree that the bytecode filter is probably not the way to solve this. JDK-8331307 has been created to redo Because this issue is creating false positives in testing I propose that we first remove the verification so it can be redone. Reverted the test and removed the verification logic. |
Added tag jdk-23+20 for changeset 87e864b
Thanks for the reviews. /integrate |
Going to push as commit 9b423a8.
Your commit was automatically rebased without conflicts. |
The verification added in JDK-8329757 will not work when deoptimization occurs on a monitorenter bytecode. The locking may be in a transitional state. Because the correct solution is still not obvious and this test is currently only causing false positives, remove the verification for now.
Redo this verification in JDK-8331307.
Removal tested GHA and tier 1-3.
Progress
Issue
Reviewers
Contributors
<pchilanomate@openjdk.org>
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/18782/head:pull/18782
$ git checkout pull/18782
Update a local copy of the PR:
$ git checkout pull/18782
$ git pull https://git.openjdk.org/jdk.git pull/18782/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 18782
View PR using the GUI difftool:
$ git pr show -t 18782
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/18782.diff
Webrev
Link to Webrev Comment