in core/src/main/java/com/jetbrains/sa/jdi/ThreadReferenceImpl.java [224:292]
private void ownedMonitorsWithStackDepth() {
ownedMonitorsInfo = new ArrayList<MonitorInfoImpl>();
List<OopHandle> lockedObjects = new ArrayList<OopHandle>(); // List<OopHandle>
List<Integer> stackDepth = new ArrayList<Integer>(); // List<int>
ObjectMonitor waitingMonitor = myJavaThread.getCurrentWaitingMonitor();
ObjectMonitor pendingMonitor = myJavaThread.getCurrentPendingMonitor();
OopHandle waitingObj = null;
if (waitingMonitor != null) {
// save object of current wait() call (if any) for later comparison
waitingObj = waitingMonitor.object();
}
OopHandle pendingObj = null;
if (pendingMonitor != null) {
// save object of current enter() call (if any) for later comparison
pendingObj = pendingMonitor.object();
}
JavaVFrame frame = myJavaThread.getLastJavaVFrameDbg();
int depth=0;
while (frame != null) {
for (Object frameMonitor : JvmUtils.getFrameMonitors(frame)) {
MonitorInfo mi = (MonitorInfo) frameMonitor;
if (mi.eliminated() && frame.isCompiledFrame()) {
continue; // skip eliminated monitor
}
OopHandle obj = mi.owner();
if (obj == null) {
// this monitor doesn't have an owning object so skip it
continue;
}
if (obj.equals(waitingObj)) {
// the thread is waiting on this monitor so it isn't really owned
continue;
}
if (obj.equals(pendingObj)) {
// the thread is pending on this monitor so it isn't really owned
continue;
}
boolean found = false;
for (Object lockedObject : lockedObjects) {
// check for recursive locks
if (obj.equals(lockedObject)) {
found = true;
break;
}
}
if (found) {
// already have this object so don't include it
continue;
}
// add the owning object to our list
lockedObjects.add(obj);
stackDepth.add(depth);
}
frame = JvmUtils.getFrameJavaSender(frame);
depth++;
}
// now convert List<OopHandle> to List<ObjectReference>
ObjectHeap heap = vm().saObjectHeap();
Iterator<Integer> stk = stackDepth.iterator();
for (OopHandle lockedObject : lockedObjects) {
ownedMonitorsInfo.add(new MonitorInfoImpl(vm().objectMirror(lockedObject), this, stk.next()));
}
}