RFR: 8357650: ThreadSnapshot to take snapshot of thread for thread dumps [v2]
David Holmes
dholmes at openjdk.org
Wed May 28 08:06:56 UTC 2025
On Tue, 27 May 2025 22:48:15 GMT, Alex Menkov <amenkov at openjdk.org> wrote:
>> This is first (hotspot) part of the update for `HotSpotDiagnosticMXBean.dumpThreads` and `jcmd Thread.dump_to_file` to include lock information in thread dumps (JDK-8356870).
>> The update has been split into parts to simplify reviewing.
>> The fix contains an implementation of `jdk.internal.vm.ThreadSnapshot` class to gather required information about a thread.
>> Second (dependent) part includes changes in `HotSpotDiagnosticMXBean.dumpThreads`/`jcmd Thread.dump_to_file`, spec updates and tests for the functionality.
>>
>> Testing: new `HotSpotDiagnosticMXBean.dumpThreads`/`jcmd Thread.dump_to_file` functionality was tested in loom repo;
>> sanity tier1 (this fix only)
>
> Alex Menkov has updated the pull request incrementally with one additional commit since the last revision:
>
> move to ThreadService
Some initial drive-by comments ...
src/hotspot/share/classfile/javaClasses.cpp line 1875:
> 1873:
> 1874: oop java_lang_Thread::park_blocker(oop java_thread) {
> 1875: return java_thread->obj_field_acquire(_park_blocker_offset);
Where is the releasing store that pairs with this load-acquire?
src/hotspot/share/prims/jvmtiThreadState.hpp line 80:
> 78: // Virtual Thread Mount State Transition (VTMS transition) mechanism
> 79: //
> 80: class JvmtiVTMSTransitionDisabler : public AnyObj {
Why this change?
src/hotspot/share/services/threadService.cpp line 1170:
> 1168: };
> 1169:
> 1170: Handle _java_thread;
Suggestion:
Handle h_java_thread;
The use of the `h_` prefix for a variable that is a handle is not uncommon and makes it clearer it is a handle, especially when applying the `()` operator.
src/hotspot/share/services/threadService.cpp line 1189:
> 1187: _thread_status(), _name(nullptr),
> 1188: _locks(nullptr), _blocker(), _blocker_owner(nullptr) { }
> 1189: virtual ~GetThreadSnapshotClosure() {
Suggestion:
_locks(nullptr), _blocker(), _blocker_owner(nullptr) {
}
virtual ~GetThreadSnapshotClosure() {
src/hotspot/share/services/threadService.cpp line 1203:
> 1201: }
> 1202:
> 1203: bool read_reset_retry() {
What does the `read` mean in the name?
src/hotspot/share/services/threadService.cpp line 1206:
> 1204: bool ret = _retry_handshake;
> 1205: // If we re-execute the handshake this method need to return false
> 1206: // when the handshake cannot be performed. (E.g. thread terminating)
Unclear what the comment means. The "retry" logic needs to be clearly explained somewhere.
src/hotspot/share/services/threadService.cpp line 1262:
> 1260: // The first stage of async deflation does not affect any field
> 1261: // used by this comparison so the ObjectMonitor* is usable here.
> 1262: if (mark.has_monitor()) {
Does this depend on locking mode and non-compact-headers?
src/hotspot/share/services/threadService.cpp line 1434:
> 1432: static Handle allocate(InstanceKlass* klass, TRAPS) {
> 1433: init(klass, CHECK_NH);
> 1434: return klass->allocate_instance_handle(CHECK_NH);
Suggestion:
return klass->allocate_instance_handle(CHECK_NH);
Suggestion:
Handle h_k = klass->allocate_instance_handle(CHECK_NH);
return h_k;
You can't use `CHECK` on a `return` statement.
src/hotspot/share/services/threadService.cpp line 1528:
> 1526: // StackTrace
> 1527: InstanceKlass* ste_klass = vmClasses::StackTraceElement_klass();
> 1528: assert(ste_klass != nullptr, "must be loaded in 1.4+");
Suggestion:
assert(ste_klass != nullptr, "must be loaded");
The 1.4+ is not relevant these days
src/hotspot/share/services/threadService.cpp line 1531:
> 1529: if (ste_klass->should_be_initialized()) {
> 1530: ste_klass->initialize(CHECK_NULL);
> 1531: }
Is this actually necessary? Doesn't this klass always get initialized as part of VM initialization?
src/hotspot/share/services/threadService.cpp line 1560:
> 1558: // call static StackTraceElement[] StackTraceElement.of(StackTraceElement[] stackTrace)
> 1559: // to properly initialize STE.
> 1560: {
Why the additional block scope?
-------------
PR Review: https://git.openjdk.org/jdk/pull/25425#pullrequestreview-2873829619
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111086253
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111089461
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111102216
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111108369
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111110893
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111112004
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111195897
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111202668
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111206814
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111207890
PR Review Comment: https://git.openjdk.org/jdk/pull/25425#discussion_r2111210020
More information about the hotspot-dev
mailing list