Skip to content

Commit

Permalink
Merge pull request #11155 from gacholio/owned
Browse files Browse the repository at this point in the history
Exclude waiting objects from owned monitor queries
  • Loading branch information
pshipton committed Nov 12, 2020
2 parents 0676066 + 966c0a9 commit e8d57b0
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 14 deletions.
16 changes: 13 additions & 3 deletions runtime/codert_vm/jswalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1769,6 +1769,9 @@ walkLiveMonitorSlots(J9StackWalkState *walkState, J9JITStackAtlas *gcStackAtlas,
j9object_t *objAddress;
U_16 i;
U_8 bit;
J9VMThread *currentThread = walkState->currentThread;
J9VMThread *targetThread = walkState->walkThread;
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;

for (i = 0; i < numberOfMapBits; ++i) {
bit = liveMonitorMap[i >> 3] & monitorMask[i >> 3] & (1 << (i & 7));
Expand All @@ -1786,7 +1789,7 @@ walkLiveMonitorSlots(J9StackWalkState *walkState, J9JITStackAtlas *gcStackAtlas,
if (NULL != objAddress) {
j9object_t obj = *objAddress;

if (NULL != obj) {
if ((NULL != obj) && !vmFuncs->objectIsBeingWaitedOn(currentThread, targetThread, obj)) {
info->object = obj;
info->count = 1;
info->depth = (UDATA)walkState->userData4;
Expand All @@ -1806,6 +1809,9 @@ countLiveMonitorSlots(J9StackWalkState *walkState, J9JITStackAtlas *gcStackAtlas
IDATA monitorCount = (IDATA)walkState->userData2;
U_16 i;
U_8 bit;
J9VMThread *currentThread = walkState->currentThread;
J9VMThread *targetThread = walkState->walkThread;
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;

for (i = 0; i < numberOfMapBits; ++i) {
bit = liveMonitorMap[i >> 3] & monitorMask[i >> 3];
Expand All @@ -1816,8 +1822,12 @@ countLiveMonitorSlots(J9StackWalkState *walkState, J9JITStackAtlas *gcStackAtlas
/* CMVC 188386 : if the object is stack allocates and the object is discontiguous on stack,
* the jit stores a null in the slot. Skip this slot.
*/
if ((NULL != objAddress) && (NULL != *objAddress)) {
monitorCount += 1;
if (NULL != objAddress) {
j9object_t obj = *objAddress;

if ((NULL != obj) && !vmFuncs->objectIsBeingWaitedOn(currentThread, targetThread, obj)) {
monitorCount += 1;
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4654,6 +4654,7 @@ typedef struct J9InternalVMFunctions {
void ( *storeFlattenableArrayElement)(struct J9VMThread *currentThread, j9object_t receiverObject, U_32 index, j9object_t paramObject);
j9object_t ( *loadFlattenableArrayElement)(struct J9VMThread *currentThread, j9object_t receiverObject, U_32 index, BOOLEAN fast);
UDATA ( *jniIsInternalClassRef)(struct J9JavaVM *vm, jobject ref);
BOOLEAN (*objectIsBeingWaitedOn)(struct J9VMThread *currentThread, struct J9VMThread *targetThread, j9object_t obj);
} J9InternalVMFunctions;

/* Jazz 99339: define a new structure to replace JavaVM so as to pass J9NativeLibrary to JVMTIEnv */
Expand Down
10 changes: 10 additions & 0 deletions runtime/oti/vm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -4243,6 +4243,16 @@ typedef struct J9ObjectMonitorInfo {
UDATA count;
} J9ObjectMonitorInfo;

/**
* @brief See if an object is being waited on by targetThread
* @param currentThread
* @param targetThread
* @param obj
* @return BOOLEAN
*/
BOOLEAN
objectIsBeingWaitedOn(J9VMThread *currentThread, J9VMThread *targetThread, j9object_t obj);

/**
* @brief Get the object monitors locked by a thread
* @param currentThread
Expand Down
3 changes: 2 additions & 1 deletion runtime/vm/intfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,5 +392,6 @@ J9InternalVMFunctions J9InternalFunctions = {
#endif /* JAVA_SPEC_VERSION >= 15 */
storeFlattenableArrayElement,
loadFlattenableArrayElement,
jniIsInternalClassRef
jniIsInternalClassRef,
objectIsBeingWaitedOn,
};
35 changes: 25 additions & 10 deletions runtime/vm/ownedmonitors.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2017 IBM Corp. and others
* Copyright (c) 2001, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -29,9 +29,19 @@
static UDATA getOwnedObjectMonitorsIterator(J9VMThread *currentThread, J9StackWalkState *walkState);
static UDATA walkFrameMonitorEnterRecords(J9VMThread *currentThread, J9StackWalkState *walkState);
static IDATA getJNIMonitors(J9VMThread *currentThread, J9VMThread *targetThread, J9ObjectMonitorInfo *minfoStart, J9ObjectMonitorInfo *minfoEnd);
static IDATA countMonitorEnterRecords(J9VMThread *targetThread);
static IDATA countMonitorEnterRecords(J9VMThread *currentThread, J9VMThread *targetThread);


BOOLEAN
objectIsBeingWaitedOn(J9VMThread *currentThread, J9VMThread *targetThread, j9object_t obj)
{
BOOLEAN rc = FALSE;
if (J9_ARE_ANY_BITS_SET(targetThread->publicFlags, J9_PUBLIC_FLAGS_THREAD_WAITING)) {
rc = (obj == J9VMTHREAD_BLOCKINGENTEROBJECT(currentThread, targetThread));
}
return rc;
}

/**
* Get the object monitors owned by a thread
* @param[in] currentThread
Expand Down Expand Up @@ -89,7 +99,7 @@ getOwnedObjectMonitors(J9VMThread *currentThread, J9VMThread *targetThread,
if (rc < 0) {
return J9_GETOWNEDMONITORS_ERROR;
}
rc += countMonitorEnterRecords(targetThread);
rc += countMonitorEnterRecords(currentThread, targetThread);
} else {
getJNIMonitors(currentThread, targetThread, walkState.userData1, walkState.userData2);
rc = infoLen;
Expand Down Expand Up @@ -136,8 +146,8 @@ walkFrameMonitorEnterRecords(J9VMThread *currentThread, J9StackWalkState *walkSt
J9ObjectMonitorInfo *lastInfo = walkState->userData2;
U_32 modifiers;
UDATA *frameID;

IDATA monitorCount = (IDATA)walkState->userData2;
J9VMThread *targetThread = walkState->walkThread;

/*
* Walk the monitor enter records from this frame and
Expand All @@ -154,16 +164,17 @@ walkFrameMonitorEnterRecords(J9VMThread *currentThread, J9StackWalkState *walkSt
while (monitorEnterRecords &&
(frameID == CONVERT_FROM_RELATIVE_STACK_OFFSET(walkState->walkThread, monitorEnterRecords->arg0EA))
) {
j9object_t obj = monitorEnterRecords->object;
/* Do not report monitors for stack allocated objects */
if (!isObjectStackAllocated(walkState->walkThread, monitorEnterRecords->object)) {
if (!(isObjectStackAllocated(targetThread, obj) || objectIsBeingWaitedOn(currentThread, targetThread, obj))) {
if (NULL == info) {
++monitorCount;
} else {
if (info > lastInfo) {
/* Don't overflow the MonitorInfo array */
return J9_STACKWALK_STOP_ITERATING;
}
info->object = monitorEnterRecords->object;
info->object = obj;
info->count = monitorEnterRecords->dropEnterCount;
info->depth = (IDATA) walkState->userData4;
info++;
Expand Down Expand Up @@ -192,7 +203,7 @@ walkFrameMonitorEnterRecords(J9VMThread *currentThread, J9StackWalkState *walkSt
}

/* Do not report monitors for stack allocated objects */
if ((!isObjectStackAllocated(walkState->walkThread, syncObject))) {
if (!(isObjectStackAllocated(targetThread, syncObject) || objectIsBeingWaitedOn(currentThread, targetThread, syncObject))) {
if (NULL == info) {
++monitorCount;
} else {
Expand Down Expand Up @@ -227,12 +238,14 @@ getJNIMonitors(J9VMThread *currentThread, J9VMThread *targetThread, J9ObjectMoni

enterRecord = targetThread->jniMonitorEnterRecords;
while (enterRecord != NULL) {
j9object_t obj = enterRecord->object;

if (minfo > lastInfo) {
/* Don't overflow the MonitorInfo array */
return count;
}
/* Do not report monitors for stack allocated objects */
if (!isObjectStackAllocated(targetThread, enterRecord->object)) {
if (!(isObjectStackAllocated(targetThread, obj) || objectIsBeingWaitedOn(currentThread, targetThread, obj))) {
minfo->object = enterRecord->object;
minfo->count = enterRecord->dropEnterCount;
minfo->depth = 0;
Expand All @@ -250,13 +263,15 @@ getJNIMonitors(J9VMThread *currentThread, J9VMThread *targetThread, J9ObjectMoni
* >=0 - number of records in list
*/
static IDATA
countMonitorEnterRecords(J9VMThread *targetThread)
countMonitorEnterRecords(J9VMThread *currentThread, J9VMThread *targetThread)
{
IDATA count = 0;
J9MonitorEnterRecord *rec = targetThread->jniMonitorEnterRecords;

while (rec != NULL) {
if (!isObjectStackAllocated(targetThread, rec->object)) {
j9object_t obj = rec->object;

if (!(isObjectStackAllocated(targetThread, obj) || objectIsBeingWaitedOn(currentThread, targetThread, obj))) {
++count;
}
rec = rec->next;
Expand Down

0 comments on commit e8d57b0

Please sign in to comment.