|
9 | 9 | #include <stdarg.h> |
10 | 10 | #include "vmStructs.h" |
11 | 11 | #include "vmEntry.h" |
| 12 | +#include "context.h" |
| 13 | +#include "thread.h" |
12 | 14 | #include "j9Ext.h" |
13 | 15 | #include "jniHelper.h" |
14 | 16 | #include "jvmHeap.h" |
@@ -675,6 +677,38 @@ int VMThread::osThreadId() { |
675 | 677 | return -1; |
676 | 678 | } |
677 | 679 |
|
| 680 | +u64 VMThread::monitorOwnerSpanId(const void* object) { |
| 681 | + if (_monitor_owner_offset == 0) return 0; |
| 682 | + |
| 683 | + // Read the mark word from the object header. |
| 684 | + uintptr_t mark = (uintptr_t)SafeAccess::load((void**)object, nullptr); |
| 685 | + |
| 686 | + // At MonitorContendedEnter time the monitor must be inflated (MONITOR_BIT set |
| 687 | + // in bits [1:0]). Guard defensively for any narrow races. |
| 688 | + if ((mark & 0x3) != MONITOR_BIT) return 0; |
| 689 | + |
| 690 | + // Extract ObjectMonitor* (pointer stored in bits 63:2, 4-byte aligned). |
| 691 | + const char* monitor = (const char*)(mark & ~(uintptr_t)0x3); |
| 692 | + |
| 693 | + // Read ObjectMonitor::_owner (JavaThread*). |
| 694 | + const char* owner_thread = (const char*)SafeAccess::load( |
| 695 | + (void**)(monitor + _monitor_owner_offset), nullptr); |
| 696 | + if (owner_thread == nullptr) return 0; |
| 697 | + |
| 698 | + // JavaThread* -> OS thread ID via existing VMThread infrastructure. |
| 699 | + int owner_tid = VMThread::cast(owner_thread)->osThreadId(); |
| 700 | + if (owner_tid <= 0) return 0; |
| 701 | + |
| 702 | + // OS thread ID -> ProfiledThread* -> span ID. |
| 703 | + ProfiledThread* owner = ProfiledThread::findByTid(owner_tid); |
| 704 | + if (owner == nullptr || !owner->isContextTlsInitialized()) return 0; |
| 705 | + |
| 706 | + Context* ctx = owner->getContextTlsPtr(); |
| 707 | + if (ctx == nullptr) return 0; |
| 708 | + |
| 709 | + return ctx->spanId; // volatile u64, safe to read cross-thread on x86/aarch64 |
| 710 | +} |
| 711 | + |
678 | 712 | JNIEnv* VMThread::jni() { |
679 | 713 | if (_env_offset < 0) { |
680 | 714 | return VM::jni(); // fallback for non-HotSpot JVM |
|
0 commit comments