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
8273000: Remove WeakReference-based class initialisation barrier implementation #5258
Conversation
Unsafe::ensureClassInitialized()
/shouldBeInitialized()
.
|
Webrevs
|
I'm unclear exactly what that statement is meant to indicate. The thread actually running "clinit" does not block due to the initialization process, but will block if the class initialization code blocks. If the class is not initialized and you are racing with another thread doing the initialization then you may block until that initialization is complete. |
The call to But when call to
In the former case, it's safe to remove the barrier while in the latter the barrier is still required. |
That's a nice cleanup to a tricky area (one of the few used to trigger an update a final field). In effect we were already relying on that behavior in the ClassValue
computation.
May i suggest that we add some JavaDoc to ensureClassInitialized
describing the two cases of the calling thread is the initialization thread or not.
@iwanowww This change now passes all automated pre-integration checks. 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 96 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.
|
UNSAFE.ensureClassInitialized(defc); // initialization barrier; blocks unless called by the initializing thread | ||
return !UNSAFE.shouldBeInitialized(defc); // keep the barrier if the initialization is still in progress |
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 some more elaborate commentary about the possibility of this being called while <clinit> of defc is already on the call stack, would be worthwhile - the existing comments are a little too subtle IMO.
UNSAFE.ensureClassInitialized(defc);
// Once we get here either defc was fully initialized by another thread, or
// defc was already being initialized by the current thread. In the latter case
// the barrier must remain. We can detect this simply by checking if initialization
// is still needed.
return !UNSAFE.shouldBeInitialized(defc);
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, David. I incorporated your suggestion in the latest version.
This is a good suggestion that also applies to |
Thanks, Paul. How does the latest version look? |
Looks good, just a minor suggestion up to you to accept or not.
* The call returns when either class {@code c} is fully initialized or | ||
* class {@code c} is being initialized and the call is performed from | ||
* the initializing 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.
* The call returns when either class {@code c} is fully initialized or | |
* class {@code c} is being initialized and the call is performed from | |
* the initializing thread. | |
* The call returns when either class {@code c} is fully initialized or | |
* class {@code c} is being initialized and the call is performed from | |
* the initializing thread. In the latter case a subsequent call to | |
* {@link #shouldBeInitialized}, from the calling thread of this call, | |
* will return {@code 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.
Aren't "the calling thread of this call" and "the initializing thread" the same thread in the latter case?
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.
Agree. I dropped "from the calling thread of this call" part and incorporated the rest into the latest version.
Thanks for the reviews, Mandy, Paul, and David. /integrate |
Going to push as commit faa942c.
Your commit was automatically rebased without conflicts. |
Get rid of WeakReference-based logic in DirectMethodHandle::checkInitialized() and reimplement it with
Unsafe::ensureClassInitialized()
/shouldBeInitialized()
.The key observation is that
Unsafe::ensureClassInitialized()
does not block the initializing thread.Also, removed
Unsafe::shouldBeInitialized()
inDMH::shouldBeInitialized(MemberName)
to save on calling into the VM.Unsafe::ensureClassInitialized()
already has a fast-path check which checks whether the class is fully initialized or not.Testing: tier1 - tier6
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/5258/head:pull/5258
$ git checkout pull/5258
Update a local copy of the PR:
$ git checkout pull/5258
$ git pull https://git.openjdk.java.net/jdk pull/5258/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 5258
View PR using the GUI difftool:
$ git pr show -t 5258
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/5258.diff