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