Skip to content

Commit 8502470

Browse files
authored
Merge pull request #21356 from tajila/jfrbackport
(0.51) Fix owner for JFR monitor enter
2 parents b8730cf + b73f590 commit 8502470

File tree

6 files changed

+51
-7
lines changed

6 files changed

+51
-7
lines changed

runtime/vm/JFRChunkWriter.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,13 +596,13 @@ class VM_JFRChunkWriter {
596596
VM_BufferWriter *_bufferWriter = (VM_BufferWriter *)userData;
597597

598598
/* reserve size field */
599-
U_8 *dataStart = _bufferWriter->getAndIncCursor(sizeof(U_32));
599+
U_8 *dataStart = reserveEventSize(_bufferWriter);
600600

601601
/* write event type */
602602
_bufferWriter->writeLEB128(MonitorEnterID);
603603

604-
/* write start time - this is when the sleep started not when it ended so we
605-
* need to subtract the duration since the event is emitted when the sleep ends.
604+
/* write start time - this is when the monitor enter started not when it ended so we
605+
* need to subtract the duration since the event is emitted when the monitor enter ends.
606606
*/
607607
_bufferWriter->writeLEB128(entry->ticks - entry->duration);
608608

runtime/vm/JFRConstantPoolTypes.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -770,12 +770,25 @@ VM_JFRConstantPoolTypes::addThreadEntry(J9VMThread *vmThread)
770770
U_32 index = U_32_MAX;
771771
ThreadEntry *entry = NULL;
772772
ThreadEntry entryBuffer = {0};
773+
omrthread_t osThread = NULL;
774+
j9object_t threadObject = NULL;
775+
776+
if (NULL == vmThread) {
777+
index = 0;
778+
goto done;
779+
}
773780

774781
entry = &entryBuffer;
775782
entry->vmThread = vmThread;
776783
_buildResult = OK;
777-
omrthread_t osThread = vmThread->osThread;
778-
j9object_t threadObject = vmThread->threadObject;
784+
osThread = vmThread->osThread;
785+
threadObject = vmThread->threadObject;
786+
787+
if ((NULL == osThread) || (NULL == threadObject)) {
788+
/* this can happen if a thread dies during a monitor enter */
789+
index = 0;
790+
goto done;
791+
}
779792

780793
entry = (ThreadEntry *) hashTableFind(_threadTable, entry);
781794
if (NULL != entry) {
@@ -1102,6 +1115,9 @@ VM_JFRConstantPoolTypes::addMonitorEnterEntry(J9JFRMonitorEntered *monitorEnterD
11021115
entry->threadIndex = addThreadEntry(monitorEnterData->vmThread);
11031116
if (isResultNotOKay()) goto done;
11041117

1118+
entry->previousOwnerThread = addThreadEntry(monitorEnterData->previousOwner);
1119+
if (isResultNotOKay()) goto done;
1120+
11051121
entry->eventThreadIndex = addThreadEntry(monitorEnterData->vmThread);
11061122
if (isResultNotOKay()) goto done;
11071123

runtime/vm/ObjectMonitor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ objectMonitorEnterBlocking(J9VMThread *currentThread)
168168
object = NULL; // for safety, since object may be moved by the GC at various points after this
169169
/* Ensure object monitor isn't deflated while we block */
170170
omrthread_monitor_t monitor = objectMonitor->monitor;
171+
J9VMThread *previousOwner = getVMThreadFromOMRThread(vm, ((J9ThreadMonitor *)monitor)->owner);
171172
VM_AtomicSupport::add(&monitor->pinCount, 1);
172173
/* Initialize our wait time to 1ms. Increase it as we have to wait more and more
173174
* using the sequence 1, 4, 16, 64 and then 64 thereafter.
@@ -291,9 +292,8 @@ objectMonitorEnterBlocking(J9VMThread *currentThread)
291292
((J9ThreadMonitor*)monitor)->flags &= ~(UDATA)J9THREAD_MONITOR_SUPPRESS_CONTENDED_EXIT;
292293
VM_AtomicSupport::subtract(&monitor->pinCount, 1);
293294
if (J9_EVENT_IS_HOOKED(vm->hookInterface, J9HOOK_VM_MONITOR_CONTENDED_ENTERED)) {
294-
J9VMThread *ownerThread = getVMThreadFromOMRThread(vm, ((J9ThreadMonitor *)monitor)->owner);
295295
bool frameBuilt = saveBlockingEnterObject(currentThread);
296-
ALWAYS_TRIGGER_J9HOOK_VM_MONITOR_CONTENDED_ENTERED(vm->hookInterface, currentThread, monitor, startTicks, ramClass, ownerThread);
296+
ALWAYS_TRIGGER_J9HOOK_VM_MONITOR_CONTENDED_ENTERED(vm->hookInterface, currentThread, monitor, startTicks, ramClass, previousOwner);
297297
restoreBlockingEnterObject(currentThread, frameBuilt);
298298
}
299299
}

runtime/vm/jfr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ jfrVMMonitorEntered(J9HookInterface **hook, UDATA eventNum, void *eventData, voi
696696
jfrEvent->duration = j9time_nano_time() - event->startTicks;
697697
jfrEvent->monitorClass = event->monitorClass;
698698
jfrEvent->monitorAddress = (UDATA)event->monitor;
699+
jfrEvent->previousOwner = event->previousOwner;
699700
}
700701
}
701702

test/functional/cmdLineTests/jfr/jfrevents.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,15 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
6464
<output type="success" caseSensitive="yes" regex="no">stackTrace</output>
6565
<output type="failure" caseSensitive="yes" regex="no">jfr print: could not read recording</output>
6666
</test>
67+
<test id="test jfr monitor enter - approx 30seconds">
68+
<command>$JFR_EXE$ print --xml --events "JavaMonitorEnter" --stack-depth 1 defaultJ9recording.jfr</command>
69+
<output type="required" caseSensitive="yes" regex="no">http://www.w3.org/2001/XMLSchema-instance</output>
70+
<output type="required" caseSensitive="yes" regex="no">jdk.JavaMonitorEnter</output>
71+
<output type="required" caseSensitive="yes" regex="no">eventThread</output>
72+
<output type="required" caseSensitive="yes" regex="no">osName</output>
73+
<output type="required" caseSensitive="yes" regex="no">osThreadId</output>
74+
<output type="required" caseSensitive="yes" regex="no">javaName</output>
75+
<output type="success" caseSensitive="yes" regex="no">stackTrace</output>
76+
<output type="failure" caseSensitive="yes" regex="no">jfr print: could not read recording</output>
77+
</test>
6778
</suite>

test/functional/cmdLineTests/jfr/src/org/openj9/test/WorkLoad.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ public class WorkLoad {
3535
public static double average;
3636
public static double stdDev;
3737

38+
private static long globalCounter = 0;
39+
static interface GlobalLoack {};
40+
private static Object globalLock = new GlobalLoack(){};
41+
3842
public WorkLoad(int numberOfThreads, int sizeOfNumberList, int repeats) {
3943
this.numberOfThreads = numberOfThreads;
4044
this.sizeOfNumberList = sizeOfNumberList;
@@ -93,10 +97,22 @@ private void workload() {
9397
generateTimedSleep();
9498
generateTimedWait();
9599
throwThrowables();
100+
contendOnLock();
96101
burnCPU();
97102
}
98103
}
99104

105+
private void contendOnLock() {
106+
synchronized (globalLock) {
107+
globalCounter++;
108+
try {
109+
Thread.sleep(1);
110+
} catch (InterruptedException e) {
111+
e.printStackTrace();
112+
}
113+
}
114+
}
115+
100116
private void recursiveFucntion(int depth) {
101117
if (0 == depth) {
102118
return;

0 commit comments

Comments
 (0)