On Mon, 15 Jul 2024 00:44:31 GMT, Axel Boldt-Christmas <abold...@openjdk.org> 
wrote:

>> src/hotspot/share/runtime/basicLock.cpp line 37:
>> 
>>> 35:     if (mon != nullptr) {
>>> 36:       mon->print_on(st);
>>> 37:     }
>> 
>> I am not sure if we wanted to do this, but we know the owner, therefore we 
>> could also look-up the OM from the table, and print it. It wouldn't have all 
>> that much to do with the BasicLock, though.
>
> Yeah maybe it is unwanted. Not sure how we should treat these prints of the 
> frames. My thinking was that there is something in the cache, print it. But 
> maybe just treating it as some internal data, maybe print "monitor { <Cached 
> ObjectMonitor* address> }" or similar is better.

It seems generally useful to print the monitor in the cache if it's there.  I 
don't think we should do a table search here.  I think this looks fine as it 
is, and might be helpful for debugging if it turns out to be the wrong monitor.

>> src/hotspot/share/runtime/lightweightSynchronizer.cpp line 80:
>> 
>>> 78: 
>>> 79:   ConcurrentTable* _table;
>>> 80:   volatile size_t _table_count;
>> 
>> Looks like a misnomer to me. We only have one table, but we do have N 
>> entries/nodes. This is counted when new nodes are allocated or old nodes are 
>> freed. Consider renaming this to '_entry_count' or '_node_count'? I'm 
>> actually a bit surprised if ConcurrentHashTable doesn't already track this...
>
> I think I was thinking of the names as a prefix to refer to the `Count of the 
> table` and `Size of the table`. And not the `Number of tables`. But I can see 
> the confusion. 
> 
> `ConcurrentHashTable` tracks no statistics except for JFR which added some 
> counters directly into the implementation. All statistics are for the users 
> to manage, even if there are helpers for gather these statistics. 
> 
> The current implementation is based on what we do for the StringTable and 
> SymbolTable

In the other tables, it's called _items_count and it determines the load_factor 
for triggering concurrent work.  We should rename this field items_count to 
match, and also since it's consistent.

>> src/hotspot/share/runtime/lightweightSynchronizer.cpp line 159:
>> 
>>> 157:   static size_t min_log_size() {
>>> 158:     // ~= log(AvgMonitorsPerThreadEstimate default)
>>> 159:     return 10;
>> 
>> Uh wait - are we assuming that threads hold 1024 monitors *on average* ? 
>> Isn't this a bit excessive? I would have thought maybe 8 monitors/thread. 
>> Yes there are workloads that are bonkers. Or maybe the comment/flag name 
>> does not say what I think it says.
>> 
>> Or why not use AvgMonitorsPerThreadEstimate directly?
>
> Maybe that is resonable. I believe I had that at some point but it had to 
> deal with how to handle extreme values of `AvgMonitorsPerThreadEstimate` as 
> well as what to do when `AvgMonitorsPerThreadEstimate` was disabled `=0`. One 
> 4 / 8 KB allocation seems harmless.
> 
> But this was very arbitrary. This will probably be changed when/if the 
> resizing of the table becomes more synchronised with deflation, allowing for 
> shrinking the table.

Shrinking the table is NYI.  Maybe we should revisit this initial value then.

>> src/hotspot/share/runtime/lightweightSynchronizer.cpp line 563:
>> 
>>> 561:     assert(locking_thread == current || 
>>> locking_thread->is_obj_deopt_suspend(), "locking_thread may not run 
>>> concurrently");
>>> 562:     if (_no_safepoint) {
>>> 563:       ::new (&_nsv) NoSafepointVerifier();
>> 
>> I'm thinking that it might be easier and cleaner to just re-do what the 
>> NoSafepointVerifier does? It just calls thread->inc/dec
>> _no_safepoint_count().
>
> I wanted to avoid having to add `NoSafepointVerifier` implementation details 
> in the synchroniser code. I guess `ContinuationWrapper` already does this. 
> 
> Simply creating a `NoSafepointVerifier` when you expect no safepoint is more 
> obvious to me, shows the intent better.

This looks strange to me also, but it's be better than changing the 
no_safepoint_count directly, since NSV handles when the current thread isn't a 
JavaThread, so you'd have to duplicate that in this VerifyThreadState code too.

    NoSafepointVerifier::NoSafepointVerifier() : _thread(Thread::current()) {
      if (_thread->is_Java_thread()) {
        JavaThread::cast(_thread)->inc_no_safepoint_count();
      }
    }

>> src/hotspot/share/runtime/lightweightSynchronizer.hpp line 68:
>> 
>>> 66:   static void exit(oop object, JavaThread* current);
>>> 67: 
>>> 68:   static ObjectMonitor* inflate_into_object_header(Thread* current, 
>>> JavaThread* inflating_thread, oop object, const 
>>> ObjectSynchronizer::InflateCause cause);
>> 
>> My IDE flags this with a warning 'Parameter 'cause' is const-qualified in 
>> the function declaration; const-qualification of parameters only has an 
>> effect in function definitions' *shrugs*
>
> Yeah. The only effect is has is that you cannot reassign the variable. It was 
> the style taken from 
> [synchronizer.hpp](https://github.com/openjdk/jdk/blob/15997bc3dfe9dddf21f20fa189f97291824892de/src/hotspot/share/runtime/synchronizer.hpp)
>  where all `InflateCause` parameters are const.

Do you get this for inflate_fast_locked_object also?

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

PR Review Comment: https://git.openjdk.org/jdk/pull/20067#discussion_r1688011833
PR Review Comment: https://git.openjdk.org/jdk/pull/20067#discussion_r1688162915
PR Review Comment: https://git.openjdk.org/jdk/pull/20067#discussion_r1688378429
PR Review Comment: https://git.openjdk.org/jdk/pull/20067#discussion_r1688385921
PR Review Comment: https://git.openjdk.org/jdk/pull/20067#discussion_r1688397480

Reply via email to