8308745: ObjArrayKlass::allocate_objArray_klass may call into java while holding a lock#17739
8308745: ObjArrayKlass::allocate_objArray_klass may call into java while holding a lock#17739coleenp wants to merge 4 commits intoopenjdk:masterfrom
Conversation
|
👋 Welcome back coleenp! A progress list of the required criteria for merging this PR into |
coleenp
left a comment
There was a problem hiding this comment.
Thanks for looking at this WIP.
…ile holding a lock
Webrevs
|
|
Is the caller always a JavaThread? I'm wondering if your new recursive lock class could use the existing ObjectMonitor. I thought David asked the same question, but I can't find it. |
There has been a drive to remove |
|
@dean-long An ObjectLocker on the mirror oop for InstanceKlass might work for this but as @dholmes-ora said we've been trying to purge the ObjectLocker code from the C++ code because it's complicated by the Java Object monitor project. The JOM project may throw exceptions from the ObjectLocker constructor or destructor and the C++ code doesn't currently know what to do. We removed the ObjectLockers around class linking and some JVMTI cases. There are some in class loading but with a small amount of work, they can be removed also. The caller is always a JavaThread, some lockers are at a safepoint for traversal but the multi-arrays are only created by JavaThreads. |
|
OK, that makes sense about loom and JOM. |
| } else { | ||
| // can be called by jvmti by VMThread. | ||
| if (current->is_Java_thread()) { | ||
| _sem.wait_with_safepoint_check(JavaThread::cast(current)); |
There was a problem hiding this comment.
Why not use PlatformMutex + OSThreadWaitState instead of a semaphore?
There was a problem hiding this comment.
Semaphore seemed simpler (?)
There was a problem hiding this comment.
OK. It's a good thing HotSpot doesn't need to worry about priority-inheritance for mutexes.
There was a problem hiding this comment.
Semaphore seems simpler/cleaner and ready to use.
There was a problem hiding this comment.
It's such a rare race and unusual condition that we could execute more Java code, that I started out with just a shared bit. Then David suggested a semaphore that obeys the safepoint protocol, which seems a lot better. I've literally skimmed over OSThreadWaitState. It looks like Semaphore::wait_with_a_safepoint_check() uses it. I still don't know why it exists:
// Note: the ThreadState is legacy code and is not correctly implemented.
// Uses of ThreadState need to be replaced by the state in the JavaThread.
enum ThreadState {
Does a PlatformMutex handle priority-inheritance? It still feels like it would be overkill for this usage. I hope this RecursiveLocker does not become more widely used, where we would have to replace the simple implementation with something more difficult. We should discourage further use when possible.
There was a problem hiding this comment.
Thanks for your last comment because I was worried there's a lot of other code I should know about.
|
@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 91 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 |
coleenp
left a comment
There was a problem hiding this comment.
Thanks for your review Dean. I've retested tier1 with the changes and will send it for more. Thank you for finding the CDS bug in my change.
| } else { | ||
| // can be called by jvmti by VMThread. | ||
| if (current->is_Java_thread()) { | ||
| _sem.wait_with_safepoint_check(JavaThread::cast(current)); |
There was a problem hiding this comment.
It's such a rare race and unusual condition that we could execute more Java code, that I started out with just a shared bit. Then David suggested a semaphore that obeys the safepoint protocol, which seems a lot better. I've literally skimmed over OSThreadWaitState. It looks like Semaphore::wait_with_a_safepoint_check() uses it. I still don't know why it exists:
// Note: the ThreadState is legacy code and is not correctly implemented.
// Uses of ThreadState need to be replaced by the state in the JavaThread.
enum ThreadState {
Does a PlatformMutex handle priority-inheritance? It still feels like it would be overkill for this usage. I hope this RecursiveLocker does not become more widely used, where we would have to replace the simple implementation with something more difficult. We should discourage further use when possible.
It would depend on the OS and the mutex impementation. You can ignore my comment. It was from long ago trying to put Java on top of a real-time OS. |
dholmes-ora
left a comment
There was a problem hiding this comment.
This looks good to me. Thanks for working through the details with me.
coleenp
left a comment
There was a problem hiding this comment.
David, thank you for your discussion while fixing this problem.
| } else { | ||
| // can be called by jvmti by VMThread. | ||
| if (current->is_Java_thread()) { | ||
| _sem.wait_with_safepoint_check(JavaThread::cast(current)); |
There was a problem hiding this comment.
Thanks for your last comment because I was worried there's a lot of other code I should know about.
| { | ||
| // To get a consistent list of classes we need MultiArray_lock to ensure | ||
| // array classes aren't created during this walk. This walks through the | ||
| // array classes aren't created by another thread during this walk. This walks through the |
There was a problem hiding this comment.
Thanks for clarifying, though I'm not sure why would care given the set of classes could have changed by the time we return them anyway.
There was a problem hiding this comment.
I think in this case, we might find an ObjArrayKlass without the mirror since the Klass is added to the higher_dimension links before the mirror is created. The lock keeps them both together.
|
Thank you for reviewing, Dean, David and Fred. |
|
Going to push as commit 1877a48.
Your commit was automatically rebased without conflicts. |
This change creates a new sort of native recursive lock that can be held during JNI and Java calls, which can be used for synchronization while creating objArrayKlasses at runtime.
Passes tier1-7.
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/17739/head:pull/17739$ git checkout pull/17739Update a local copy of the PR:
$ git checkout pull/17739$ git pull https://git.openjdk.org/jdk.git pull/17739/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 17739View PR using the GUI difftool:
$ git pr show -t 17739Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/17739.diff
Webrev
Link to Webrev Comment