On Thu, 27 Oct 2022 10:58:12 GMT, Roman Kennke <rken...@openjdk.org> wrote:

>> There are several users and even mostly-identical implementations of 
>> Threads::owning_thread_from_monitor_owner(), which I would like to 
>> consolidate a little in preparation of JDK-8291555:
>> - JvmtiEnvBase::get_monitor_usage(): As the comment in 
>> ObjectSynchronizer::get_lock_owner() suggests, the JVMTI code should call 
>> the ObjectSynchronizer method. The only real difference is that JVMTI loads 
>> the object header directly while OS spins to avoid INFLATING. This is 
>> harmless, because JVMTI calls from safepoint, where INFLATING does not 
>> occur, and would just do a simple load of the header. A little care must be 
>> taken to fetch the monitor if exists a few lines below, to fill in monitor 
>> info.
>> - Two ThreadService methods call 
>> Threads::owning_thread_from_monitor_owner(), but always only ever from a 
>> monitor. I would like to extract that special case because with fast-locking 
>> this can be treated differently (with fast-locking, monitor owners can only 
>> be JavaThread* or 'anonynmous'). It's also a little cleaner IMO.
>> 
>> Testing:
>>  - [x] GHA (x86 and x-compile failures look like infra glitch)
>>  - [x] tier1
>>  - [x] tier2
>>  - [x] tier3
>>  - [x] tier4
>
> Roman Kennke has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Fix has_owner() condition

Marked as reviewed by dcubed (Reviewer).

src/hotspot/share/prims/jvmtiEnvBase.cpp line 1410:

> 1408:   if (mark.has_monitor()) {
> 1409:     mon = mark.monitor();
> 1410:     assert(mon != NULL, "must have monitor");

The original code does not have this `assert()`, but I'm okay with this.

src/hotspot/share/prims/jvmtiEnvBase.cpp line 1422:

> 1420:       // This monitor is owned so we have to find the owning JavaThread.
> 1421:       owning_thread = 
> Threads::owning_thread_from_monitor_owner(tlh.list(), owner);
> 1422:       assert(owning_thread != NULL, "owning JavaThread must not be 
> NULL");

I finished doing an equivalence analysis of this code that has been replaced 
with
the code in `ObjectSynchronizer::get_lock_owner()`. This `assert()` on L1422 is
the only thing I found that is "missing".

However, I don't think that you can add back that `assert()` call in this 
function.
The reason that the `assert()` is okay in the original code is because it is
"protected" by this line:

L1419      if (owner != NULL) {

and while that check is also done in `ObjectSynchronizer::get_lock_owner()` on
L1032, it DOES NOT `assert()` that the return from
`Threads::owning_thread_from_monitor_owner()` is not NULL and in fact
has a comment that says:

    // owning_thread_from_monitor_owner() may also return NULL here


If memory serves, `ObjectSynchronizer::get_lock_owner()` can be called from
locations where we have non-NULL `owner`, but when we try to find the owning
thread, we can sometimes get a NULL back.

src/hotspot/share/runtime/objectMonitor.inline.hpp line 61:

> 59: inline bool ObjectMonitor::has_owner() const {
> 60:   void* owner = owner_raw();
> 61:   return owner != NULL && owner != DEFLATER_MARKER;

You could also do:

    return owner() != nullptr;

and take advantage of the fact that `owner()` filters out DEFLATER_MARKER for 
you.

-------------

PR: https://git.openjdk.org/jdk/pull/10849

Reply via email to