RFR(L): 8235795: replace monitor list mux{Acquire,Release}(&gListLock) with spin locks
David Holmes
david.holmes at oracle.com
Fri Jan 24 22:42:21 UTC 2020
On 25/01/2020 4:18 am, Daniel D. Daugherty wrote:
> A follow up on audit_and_print_stats()...
>
> On 1/24/20 11:48 AM, Daniel D. Daugherty wrote:
>> On 1/23/20 9:09 PM, David Holmes wrote:
>
> <snip>
>
>>
>>>
>>>>
>>>>> ---
>>>>>
>>>>> 2189 // With fine grained locks on the monitor lists, it is
>>>>> possible for
>>>>> 2190 // log_monitor_list_counts() to return a value that
>>>>> doesn't match
>>>>> 2191 // LVars.population. So far a higher value has been seen
>>>>> in testing
>>>>> 2192 // so something is being double counted by
>>>>> log_monitor_list_counts().
>>>>>
>>>>> AFAICS this code is always executed at a safepoint so I don't
>>>>> understand how the counts could be out-of-sync. Ditto for the
>>>>> comments here:
>>>>>
>>>>> 2315 // With fine grained locks on LVars.free_list, it is
>>>>> possible for an
>>>>> 2316 // ObjectMonitor to be prepended to LVars.free_list after
>>>>> we started
>>>>> 2317 // calculating chk_om_free_count so LVars.free_count may not
>>>>> 2318 // match anymore.
>>>>>
>>>>> and here:
>>>>>
>>>>> 2346 // With fine grained locks on the monitor lists, it is
>>>>> possible for
>>>>> 2347 // an exiting JavaThread to put its in-use ObjectMonitors
>>>>> on the
>>>>> 2348 // global in-use list after chk_om_in_use_count is
>>>>> calculated above.
>>>>>
>>>>> ???
>>>>
>>>> This header comment was intended to cover that rationale:
>>>>
>>>> L2152: // This function can be called at a safepoint or it can
>>>> be called when
>>>> L2153: // we are trying to exit the VM. When we are trying to
>>>> exit the VM, the
>>>> L2154: // list walker functions can run in parallel with the
>>>> other list
>>>> L2155: // operations so spin-locking is used for safety.
>>>> L2156: //
>>>> L2157: // Calls to this function can be added in various places
>>>> as a debugging
>>>> L2158: // aid; pass 'true' for the 'on_exit' parameter to have
>>>> in-use monitor
>>>> L2159: // details logged at the Info level and 'false' for the
>>>> 'on_exit'
>>>> L2160: // parameter to have in-use monitor details logged at
>>>> the Trace level.
>>>> L2161: //
>>>> L2162: void ObjectSynchronizer::audit_and_print_stats(bool
>>>> on_exit) {
>>>>
>>>> so no the audit_and_print_stats() function and the various chk_*()
>>>> functions can be called at a non-safepoint.
>>>
>>> When we are exiting the VM this is called from exit_globals, which
>>> does execute at a safepoint - either:
>>>
>>> - from VM_Exit::do_it() (a safepoint VM op); or
>>> - from Threads::destroy_vm() after the VMThread has been terminated,
>>> which brings the VM to a safepoint first.
>>
>> Hmmm... I have this assert here:
>>
>> 2162 void ObjectSynchronizer::audit_and_print_stats(bool on_exit) {
>> 2163 assert(on_exit || SafepointSynchronize::is_at_safepoint(),
>> "invariant");
>>
>> and I remember adding the "on_exit" conditional so the assert wouldn't
>> fire. I'll investigate more...
>>
>> Also, audit_and_print_stats() calls can be added as a debugging
>> aide when chasing ObjectMonitor list issues. The way that it is
>> written, it doesn't require a safepoint (when on_exit == true).
>>
>> I'll make the minor edits mentioned above before I send out the
>> webrev for the next round of review.
>>
>> Thanks again for being such a thorough reviewer.
>>
>> Dan
>
> audit_and_print_stats() was added to the Async Monitor Deflation
> project by this changeset:
>
> changeset: 34:64accf02d468
> user: dcubed
> date: Fri Dec 21 13:52:56 2018 -0500
> summary: dcubed.monitor_deflate_conc.23,
> diff.txt.dcubed.monitor_deflate_conc.23 - Add support for
> ObjectSynchronizer::audit_and_print_stats(), called by exit_globals() at
> Info level and by finish_deflate_idle_monitors() at Debug level; add
> is_busy_async() for use by audit_and_print_stats(); restore a
> guarantee(take->object() == NULL) check in omAlloc() now that
> AsyncDeflateIdleMonitors cleanup of _object field is finished.
>
>
> Looking at my notes for that week, I was chasing tests that were failing
> due to ObjectMonitors that were keeping objects pinned. The tests were
> expecting that enough System.gc() calls would cause an unreferenced
> and collectible object to be GC'ed. This was back when we were having
> the JavaThread do its own deflation...
>
> It looks like I was using audit_and_print_stats(true) calls to probe
> the VM at different points trying to determine what was keeping the
> object pinned and why... So I was using audit_and_print_stats() at
> non-safepoint locations for debugging purposes...
Okay. If you want this ability that is fine then.
> Dan
>
> P.S.
>
> In src/hotspot/share/compiler/compileBroker.cpp:
> CompileBroker::handle_full_code_cache() calls exit_globals()
> when the ExitOnFullCodeCache is true in non-PRODUCT bits.
> I don't think we're at a safepoint for that call... :-)
> I don't see any tests that enable that flag and the default
> is false so I couldn't have run into it in my testing...
Yikes! That's not the way to exit the VM :) But we probably don't really
care. That termination path seems mid-way between a graceful exit and an
abort. With no termination safepoint it can be quite likely to run into
shutdown crashes anyway.
Cheers,
David
More information about the hotspot-runtime-dev
mailing list