RFR: 8253833: mutexLocker assert_locked_or_safepoint should not access VMThread state from non-VM-thread
David Holmes
david.holmes at oracle.com
Fri Oct 9 13:34:35 UTC 2020
On 9/10/2020 4:16 pm, Robbin Ehn wrote:
> On Thu, 8 Oct 2020 22:11:12 GMT, David Holmes <dholmes at openjdk.org> wrote:
>
>>> I was hope that "git blame" would help, but most of this code is ancient:
>>>
>>> da18495f385b (Coleen Phillimore 2019-08-22 09:51:36 -0400 166) void assert_locked_or_safepoint(const Mutex* lock) {
>>> 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 167) // check if this thread owns the lock (common case)
>>> 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 168) assert(lock != NULL, "Need non-NULL lock");
>>> 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 169) if (lock->owned_by_self()) return;
>>> 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 170) if (SafepointSynchronize::is_at_safepoint()) return;
>>> 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 171) if (!Universe::is_fully_initialized()) return;
>>> 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 172) // see if invoker of VM operation owns it
>>> 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 173) VM_Operation* op = VMThread::vm_operation();
>>> 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 174) if (op != NULL && op->calling_thread() ==
>>> lock->owner()) return; 1e71f6773659 (David Lindholm 2015-09-29 11:02:08 +0200 175) fatal("must own lock %s",
>>> lock->name()); 8153779ad32d (J. Duke 2007-12-01 00:00:00 +0000 176) }
>>>
>>> Update: Stripped the filename from the "git blame" output so it wasn't quite so wide...
>>> Update: Changing to a `code` quote helped the formatting a bit...
>>
>> The initialization bail-out was added "1.86 99/02/19 17:05:07", but no comments or associated bug report.
>
> Universe is initialized before VM thread is ready to process operations.
> So while that bail-out is true, there can never be any vm ops.
>
> I believe instead of:
> `if (!Universe::is_fully_initialized()) return;`
> We really want:
> `if (Threads::number_of_threads() == 0) return;`
> But I'm not sure and totally out of scope.
The way these things typically work is:
- code crashes because X has not yet been initialized
- X is known to be initialized when Universe::is_fully_initialized()
=> skip if !Universe::is_fully_initialized()
X likely relates to a later check that can't be made early during VM
init. So we just have to skip it. Without knowing what X actually is we
can't say if there is a more precise expression to check. Of course X
may no longer exist. :)
Cheers,
David
-----
> -------------
>
> PR: https://git.openjdk.java.net/jdk/pull/563
>
More information about the hotspot-runtime-dev
mailing list