aboutsummaryrefslogtreecommitdiff
path: root/agent
diff options
context:
space:
mode:
authorkvn <none@none>2009-06-09 16:19:10 -0700
committerkvn <none@none>2009-06-09 16:19:10 -0700
commit8b93b6c4030fc311bd1388c45ef047ccc9bd2f67 (patch)
tree4883dbfa133566925f5eb6129d216d5743734b43 /agent
parent4a637e0fb29037b55c08e767308d61594e96f5b8 (diff)
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
Summary: Disable escape analysis when jvmti/debugger is used. Add support for EA ibto SA. Reviewed-by: never
Diffstat (limited to 'agent')
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/DebugInfoReadStream.java41
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/MonitorValue.java6
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/ObjectValue.java93
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java48
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/ScopeValue.java7
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/jdi/ObjectReferenceImpl.java1
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/jdi/ThreadReferenceImpl.java3
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java25
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/InterpretedVFrame.java6
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/MonitorInfo.java31
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java11
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaThread.java4
12 files changed, 261 insertions, 15 deletions
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/DebugInfoReadStream.java b/agent/src/share/classes/sun/jvm/hotspot/code/DebugInfoReadStream.java
index 2fc3155fa..fa60c4983 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/code/DebugInfoReadStream.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/DebugInfoReadStream.java
@@ -24,23 +24,64 @@
package sun.jvm.hotspot.code;
+import java.util.*;
+
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.utilities.*;
public class DebugInfoReadStream extends CompressedReadStream {
private NMethod code;
private int InvocationEntryBCI;
+ private List objectPool; // ArrayList<ObjectValue>
public DebugInfoReadStream(NMethod code, int offset) {
super(code.scopesDataBegin(), offset);
InvocationEntryBCI = VM.getVM().getInvocationEntryBCI();
this.code = code;
+ this.objectPool = null;
+ }
+
+ public DebugInfoReadStream(NMethod code, int offset, List objectPool) {
+ super(code.scopesDataBegin(), offset);
+ InvocationEntryBCI = VM.getVM().getInvocationEntryBCI();
+ this.code = code;
+ this.objectPool = objectPool;
}
public OopHandle readOopHandle() {
return code.getOopAt(readInt());
}
+ ScopeValue readObjectValue() {
+ int id = readInt();
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(objectPool != null, "object pool does not exist");
+ for (Iterator itr = objectPool.iterator(); itr.hasNext();) {
+ ObjectValue ov = (ObjectValue) itr.next();
+ Assert.that(ov.id() != id, "should not be read twice");
+ }
+ }
+ ObjectValue result = new ObjectValue(id);
+ // Cache the object since an object field could reference it.
+ objectPool.add(result);
+ result.readObject(this);
+ return result;
+ }
+
+ ScopeValue getCachedObject() {
+ int id = readInt();
+ Assert.that(objectPool != null, "object pool does not exist");
+ for (Iterator itr = objectPool.iterator(); itr.hasNext();) {
+ ObjectValue ov = (ObjectValue) itr.next();
+ if (ov.id() == id) {
+ return ov;
+ }
+ }
+ Assert.that(false, "should not reach here");
+ return null;
+ }
+
public int readBCI() {
return readInt() + InvocationEntryBCI;
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/MonitorValue.java b/agent/src/share/classes/sun/jvm/hotspot/code/MonitorValue.java
index cf539d311..43937fc69 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/code/MonitorValue.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/MonitorValue.java
@@ -29,6 +29,7 @@ import java.io.*;
public class MonitorValue {
private ScopeValue owner;
private Location basicLock;
+ private boolean eliminated;
// FIXME: not useful yet
// MonitorValue(ScopeValue* owner, Location basic_lock);
@@ -36,10 +37,12 @@ public class MonitorValue {
public MonitorValue(DebugInfoReadStream stream) {
basicLock = new Location(stream);
owner = ScopeValue.readFrom(stream);
+ eliminated= stream.readBoolean();
}
public ScopeValue owner() { return owner; }
public Location basicLock() { return basicLock; }
+ public boolean eliminated() { return eliminated; }
// FIXME: not yet implementable
// void write_on(DebugInfoWriteStream* stream);
@@ -50,5 +53,8 @@ public class MonitorValue {
tty.print(",");
basicLock().printOn(tty);
tty.print("}");
+ if (eliminated) {
+ tty.print(" (eliminated)");
+ }
}
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/ObjectValue.java b/agent/src/share/classes/sun/jvm/hotspot/code/ObjectValue.java
new file mode 100644
index 000000000..1c38103fa
--- /dev/null
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/ObjectValue.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.code;
+
+import java.io.*;
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.utilities.*;
+
+/** An ObjectValue describes an object eliminated by escape analysis. */
+
+public class ObjectValue extends ScopeValue {
+ private int id;
+ private ScopeValue klass;
+ private List fieldsValue; // ArrayList<ScopeValue>
+
+ // Field "boolean visited" is not implemented here since
+ // it is used only a during debug info creation.
+
+ public ObjectValue(int id) {
+ this.id = id;
+ klass = null;
+ fieldsValue = new ArrayList();
+ }
+
+ public boolean isObject() { return true; }
+ public int id() { return id; }
+ public ScopeValue getKlass() { return klass; }
+ public List getFieldsValue() { return fieldsValue; }
+ public ScopeValue getFieldAt(int i) { return (ScopeValue)fieldsValue.get(i); }
+ public int fieldsSize() { return fieldsValue.size(); }
+
+ // Field "value" is always NULL here since it is used
+ // only during deoptimization of a compiled frame
+ // pointing to reallocated object.
+ public OopHandle getValue() { return null; }
+
+ /** Serialization of debugging information */
+
+ void readObject(DebugInfoReadStream stream) {
+ klass = readFrom(stream);
+ Assert.that(klass.isConstantOop(), "should be constant klass oop");
+ int length = stream.readInt();
+ for (int i = 0; i < length; i++) {
+ ScopeValue val = readFrom(stream);
+ fieldsValue.add(val);
+ }
+ }
+
+ // Printing
+
+ public void print() {
+ printOn(System.out);
+ }
+
+ public void printOn(PrintStream tty) {
+ tty.print("scalarObj[" + id + "]");
+ }
+
+ void printFieldsOn(PrintStream tty) {
+ if (fieldsValue.size() > 0) {
+ ((ScopeValue)fieldsValue.get(0)).printOn(tty);
+ }
+ for (int i = 1; i < fieldsValue.size(); i++) {
+ tty.print(", ");
+ ((ScopeValue)fieldsValue.get(i)).printOn(tty);
+ }
+ }
+
+};
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java b/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java
index b4d2d592d..e75365ae2 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java
@@ -27,8 +27,10 @@ package sun.jvm.hotspot.code;
import java.io.*;
import java.util.*;
+import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.utilities.*;
/** ScopeDescs contain the information that makes source-level
debugging of nmethods possible; each scopeDesc describes a method
@@ -45,10 +47,31 @@ public class ScopeDesc {
private int localsDecodeOffset;
private int expressionsDecodeOffset;
private int monitorsDecodeOffset;
+ /** Scalar replaced bjects pool */
+ private List objects; // ArrayList<ScopeValue>
+
public ScopeDesc(NMethod code, int decodeOffset) {
this.code = code;
this.decodeOffset = decodeOffset;
+ this.objects = decodeObjectValues(DebugInformationRecorder.SERIALIZED_NULL);
+
+ // Decode header
+ DebugInfoReadStream stream = streamAt(decodeOffset);
+
+ senderDecodeOffset = stream.readInt();
+ method = (Method) VM.getVM().getObjectHeap().newOop(stream.readOopHandle());
+ bci = stream.readBCI();
+ // Decode offsets for body and sender
+ localsDecodeOffset = stream.readInt();
+ expressionsDecodeOffset = stream.readInt();
+ monitorsDecodeOffset = stream.readInt();
+ }
+
+ public ScopeDesc(NMethod code, int decodeOffset, int objectDecodeOffset) {
+ this.code = code;
+ this.decodeOffset = decodeOffset;
+ this.objects = decodeObjectValues(objectDecodeOffset);
// Decode header
DebugInfoReadStream stream = streamAt(decodeOffset);
@@ -81,6 +104,11 @@ public class ScopeDesc {
return decodeMonitorValues(monitorsDecodeOffset);
}
+ /** Returns a List&lt;MonitorValue&gt; */
+ public List getObjects() {
+ return objects;
+ }
+
/** Stack walking. Returns null if this is the outermost scope. */
public ScopeDesc sender() {
if (isTop()) {
@@ -131,7 +159,7 @@ public class ScopeDesc {
//
private DebugInfoReadStream streamAt(int decodeOffset) {
- return new DebugInfoReadStream(code, decodeOffset);
+ return new DebugInfoReadStream(code, decodeOffset, objects);
}
/** Returns a List&lt;ScopeValue&gt; or null if no values were present */
@@ -161,4 +189,22 @@ public class ScopeDesc {
}
return res;
}
+
+ /** Returns a List&lt;ObjectValue&gt; or null if no values were present */
+ private List decodeObjectValues(int decodeOffset) {
+ if (decodeOffset == DebugInformationRecorder.SERIALIZED_NULL) {
+ return null;
+ }
+ List res = new ArrayList();
+ DebugInfoReadStream stream = new DebugInfoReadStream(code, decodeOffset, res);
+ int length = stream.readInt();
+ for (int i = 0; i < length; i++) {
+ // Objects values are pushed to 'res' array during read so that
+ // object's fields could reference it (OBJECT_ID_CODE).
+ ScopeValue.readFrom(stream);
+ // res.add(ScopeValue.readFrom(stream));
+ }
+ Assert.that(res.size() == length, "inconsistent debug information");
+ return res;
+ }
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/ScopeValue.java b/agent/src/share/classes/sun/jvm/hotspot/code/ScopeValue.java
index f9c99d3d4..71166a706 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/code/ScopeValue.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/ScopeValue.java
@@ -49,12 +49,15 @@ public abstract class ScopeValue {
static final int CONSTANT_OOP_CODE = 2;
static final int CONSTANT_LONG_CODE = 3;
static final int CONSTANT_DOUBLE_CODE = 4;
+ static final int CONSTANT_OBJECT_CODE = 5;
+ static final int CONSTANT_OBJECT_ID_CODE = 6;
public boolean isLocation() { return false; }
public boolean isConstantInt() { return false; }
public boolean isConstantDouble() { return false; }
public boolean isConstantLong() { return false; }
public boolean isConstantOop() { return false; }
+ public boolean isObject() { return false; }
public static ScopeValue readFrom(DebugInfoReadStream stream) {
switch (stream.readInt()) {
@@ -68,6 +71,10 @@ public abstract class ScopeValue {
return new ConstantLongValue(stream);
case CONSTANT_DOUBLE_CODE:
return new ConstantDoubleValue(stream);
+ case CONSTANT_OBJECT_CODE:
+ return stream.readObjectValue();
+ case CONSTANT_OBJECT_ID_CODE:
+ return stream.getCachedObject();
default:
Assert.that(false, "should not reach here");
return null;
diff --git a/agent/src/share/classes/sun/jvm/hotspot/jdi/ObjectReferenceImpl.java b/agent/src/share/classes/sun/jvm/hotspot/jdi/ObjectReferenceImpl.java
index 4911915c7..b469bde96 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ObjectReferenceImpl.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ObjectReferenceImpl.java
@@ -249,6 +249,7 @@ public class ObjectReferenceImpl extends ValueImpl implements ObjectReference {
OopHandle givenHandle = obj.getHandle();
for (Iterator itr = monitors.iterator(); itr.hasNext();) {
MonitorInfo mi = (MonitorInfo) itr.next();
+ if (mi.eliminated() && frame.isCompiledFrame()) continue; // skip eliminated monitor
if (givenHandle.equals(mi.owner())) {
res++;
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/jdi/ThreadReferenceImpl.java b/agent/src/share/classes/sun/jvm/hotspot/jdi/ThreadReferenceImpl.java
index 87dfc191f..7ae8675f4 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ThreadReferenceImpl.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ThreadReferenceImpl.java
@@ -301,6 +301,9 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
List frameMonitors = frame.getMonitors(); // List<MonitorInfo>
for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
sun.jvm.hotspot.runtime.MonitorInfo mi = (sun.jvm.hotspot.runtime.MonitorInfo) miItr.next();
+ 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
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java
index 1642fefe2..6588da2e8 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java
@@ -131,8 +131,18 @@ public class CompiledVFrame extends JavaVFrame {
List result = new ArrayList(monitors.size());
for (int i = 0; i < monitors.size(); i++) {
MonitorValue mv = (MonitorValue) monitors.get(i);
- StackValue ownerSV = createStackValue(mv.owner()); // it is an oop
- result.add(new MonitorInfo(ownerSV.getObject(), resolveMonitorLock(mv.basicLock())));
+ ScopeValue ov = mv.owner();
+ StackValue ownerSV = createStackValue(ov); // it is an oop
+ if (ov.isObject()) { // The owner object was scalar replaced
+ Assert.that(mv.eliminated() && ownerSV.objIsScalarReplaced(), "monitor should be eliminated for scalar replaced object");
+ // Put klass for scalar replaced object.
+ ScopeValue kv = ((ObjectValue)ov).getKlass();
+ Assert.that(kv.isConstantOop(), "klass should be oop constant for scalar replaced object");
+ OopHandle k = ((ConstantOopReadValue)kv).getValue();
+ result.add(new MonitorInfo(k, resolveMonitorLock(mv.basicLock()), mv.eliminated(), true));
+ } else {
+ result.add(new MonitorInfo(ownerSV.getObject(), resolveMonitorLock(mv.basicLock()), mv.eliminated(), false));
+ }
}
return result;
}
@@ -212,12 +222,12 @@ public class CompiledVFrame extends JavaVFrame {
// long or is unused. He always saves a long. Here we know
// a long was saved, but we only want an narrow oop back. Narrow the
// saved long to the narrow oop that the JVM wants.
- return new StackValue(valueAddr.getCompOopHandleAt(VM.getVM().getIntSize()));
+ return new StackValue(valueAddr.getCompOopHandleAt(VM.getVM().getIntSize()), 0);
} else {
- return new StackValue(valueAddr.getCompOopHandleAt(0));
+ return new StackValue(valueAddr.getCompOopHandleAt(0), 0);
}
} else if( loc.holdsOop() ) { // Holds an oop?
- return new StackValue(valueAddr.getOopHandleAt(0));
+ return new StackValue(valueAddr.getOopHandleAt(0), 0);
} else if( loc.holdsDouble() ) {
// Double value in a single stack slot
return new StackValue(valueAddr.getJIntAt(0) & 0xFFFFFFFF);
@@ -277,7 +287,7 @@ public class CompiledVFrame extends JavaVFrame {
return new StackValue(((ConstantIntValue) sv).getValue() & 0xFFFFFFFF);
} else if (sv.isConstantOop()) {
// constant oop
- return new StackValue(((ConstantOopReadValue) sv).getValue());
+ return new StackValue(((ConstantOopReadValue) sv).getValue(), 0);
} else if (sv.isConstantDouble()) {
// Constant double in a single stack slot
double d = ((ConstantDoubleValue) sv).getValue();
@@ -285,6 +295,9 @@ public class CompiledVFrame extends JavaVFrame {
} else if (VM.getVM().isLP64() && sv.isConstantLong()) {
// Constant long in a single stack slot
return new StackValue(((ConstantLongValue) sv).getValue() & 0xFFFFFFFF);
+ } else if (sv.isObject()) {
+ // Scalar replaced object in compiled frame
+ return new StackValue(((ObjectValue)sv).getValue(), 1);
}
// Unknown ScopeValue type
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/InterpretedVFrame.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/InterpretedVFrame.java
index ff5ad46c3..f86e4f7a2 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/InterpretedVFrame.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/InterpretedVFrame.java
@@ -61,7 +61,7 @@ public class InterpretedVFrame extends JavaVFrame {
StackValue sv;
if (oopMask.isOop(i)) {
// oop value
- sv = new StackValue(addr.getOopHandleAt(0));
+ sv = new StackValue(addr.getOopHandleAt(0), 0);
} else {
// integer
// Fetch a signed integer the size of a stack slot
@@ -95,7 +95,7 @@ public class InterpretedVFrame extends JavaVFrame {
StackValue sv;
if (oopMask.isOop(i + nofLocals)) {
// oop value
- sv = new StackValue(addr.getOopHandleAt(0));
+ sv = new StackValue(addr.getOopHandleAt(0), 0);
} else {
// integer
// Fetch a signed integer the size of a stack slot
@@ -113,7 +113,7 @@ public class InterpretedVFrame extends JavaVFrame {
for (BasicObjectLock current = getFrame().interpreterFrameMonitorEnd();
current.address().lessThan(getFrame().interpreterFrameMonitorBegin().address());
current = getFrame().nextMonitorInInterpreterFrame(current)) {
- result.add(new MonitorInfo(current.obj(), current.lock()));
+ result.add(new MonitorInfo(current.obj(), current.lock(), false, false));
}
return result;
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/MonitorInfo.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/MonitorInfo.java
index d689d4359..d4801fa05 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/MonitorInfo.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/MonitorInfo.java
@@ -25,16 +25,39 @@
package sun.jvm.hotspot.runtime;
import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.utilities.*;
public class MonitorInfo {
private OopHandle owner;
private BasicLock lock;
+ private OopHandle ownerKlass;
+ private boolean eliminated;
+ private boolean ownerIsScalarReplaced;
- public MonitorInfo(OopHandle owner, BasicLock lock) {
- this.owner = owner;
- this.lock = lock;
+ public MonitorInfo(OopHandle owner, BasicLock lock, boolean eliminated, boolean ownerIsScalarReplaced) {
+ if (!ownerIsScalarReplaced) {
+ this.owner = owner;
+ this.ownerKlass = null;
+ } else {
+ Assert.that(eliminated, "monitor should be eliminated for scalar replaced object");
+ this.owner = null;
+ this.ownerKlass = owner;
+ }
+ this.eliminated = eliminated;
+ this.ownerIsScalarReplaced = ownerIsScalarReplaced;
+ }
+
+ public OopHandle owner() {
+ Assert.that(!ownerIsScalarReplaced, "should not be called for scalar replaced object");
+ return owner;
+ }
+
+ public OopHandle ownerKlass() {
+ Assert.that(ownerIsScalarReplaced, "should not be called for not scalar replaced object");
+ return ownerKlass;
}
- public OopHandle owner() { return owner; }
public BasicLock lock() { return lock; }
+ public boolean eliminated() { return eliminated; }
+ public boolean ownerIsScalarReplaced() { return ownerIsScalarReplaced; }
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java
index 246b7098c..98becd018 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java
@@ -37,9 +37,11 @@ public class StackValue {
type = BasicType.getTConflict();
}
- public StackValue(OopHandle h) {
+ public StackValue(OopHandle h, long scalar_replaced) {
handleValue = h;
type = BasicType.getTObject();
+ integerValue = scalar_replaced;
+ Assert.that(integerValue == 0 || handleValue == null, "not null object should not be marked as scalar replaced");
}
public StackValue(long i) {
@@ -59,6 +61,13 @@ public class StackValue {
return handleValue;
}
+ boolean objIsScalarReplaced() {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(type == BasicType.getTObject(), "type check");
+ }
+ return integerValue != 0;
+ }
+
public long getInteger() {
if (Assert.ASSERTS_ENABLED) {
Assert.that(type == BasicType.getTInt(), "type check");
diff --git a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaThread.java b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaThread.java
index 40402b5a3..b8fce3abd 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaThread.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaThread.java
@@ -135,6 +135,10 @@ public class JSJavaThread extends JSJavaInstance {
List frameMonitors = frame.getMonitors(); // List<MonitorInfo>
for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
MonitorInfo mi = (MonitorInfo) miItr.next();
+
+ 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