6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
Disable escape analysis when jvmti/debugger is used. Add support for EA ibto SA. Reviewed-by: never
This commit is contained in:
parent
0429abd38a
commit
7b9d6a79ac
@ -24,23 +24,64 @@
|
|||||||
|
|
||||||
package sun.jvm.hotspot.code;
|
package sun.jvm.hotspot.code;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import sun.jvm.hotspot.debugger.*;
|
import sun.jvm.hotspot.debugger.*;
|
||||||
import sun.jvm.hotspot.runtime.VM;
|
import sun.jvm.hotspot.runtime.VM;
|
||||||
|
import sun.jvm.hotspot.utilities.*;
|
||||||
|
|
||||||
public class DebugInfoReadStream extends CompressedReadStream {
|
public class DebugInfoReadStream extends CompressedReadStream {
|
||||||
private NMethod code;
|
private NMethod code;
|
||||||
private int InvocationEntryBCI;
|
private int InvocationEntryBCI;
|
||||||
|
private List objectPool; // ArrayList<ObjectValue>
|
||||||
|
|
||||||
public DebugInfoReadStream(NMethod code, int offset) {
|
public DebugInfoReadStream(NMethod code, int offset) {
|
||||||
super(code.scopesDataBegin(), offset);
|
super(code.scopesDataBegin(), offset);
|
||||||
InvocationEntryBCI = VM.getVM().getInvocationEntryBCI();
|
InvocationEntryBCI = VM.getVM().getInvocationEntryBCI();
|
||||||
this.code = code;
|
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() {
|
public OopHandle readOopHandle() {
|
||||||
return code.getOopAt(readInt());
|
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() {
|
public int readBCI() {
|
||||||
return readInt() + InvocationEntryBCI;
|
return readInt() + InvocationEntryBCI;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import java.io.*;
|
|||||||
public class MonitorValue {
|
public class MonitorValue {
|
||||||
private ScopeValue owner;
|
private ScopeValue owner;
|
||||||
private Location basicLock;
|
private Location basicLock;
|
||||||
|
private boolean eliminated;
|
||||||
|
|
||||||
// FIXME: not useful yet
|
// FIXME: not useful yet
|
||||||
// MonitorValue(ScopeValue* owner, Location basic_lock);
|
// MonitorValue(ScopeValue* owner, Location basic_lock);
|
||||||
@ -36,10 +37,12 @@ public class MonitorValue {
|
|||||||
public MonitorValue(DebugInfoReadStream stream) {
|
public MonitorValue(DebugInfoReadStream stream) {
|
||||||
basicLock = new Location(stream);
|
basicLock = new Location(stream);
|
||||||
owner = ScopeValue.readFrom(stream);
|
owner = ScopeValue.readFrom(stream);
|
||||||
|
eliminated= stream.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScopeValue owner() { return owner; }
|
public ScopeValue owner() { return owner; }
|
||||||
public Location basicLock() { return basicLock; }
|
public Location basicLock() { return basicLock; }
|
||||||
|
public boolean eliminated() { return eliminated; }
|
||||||
|
|
||||||
// FIXME: not yet implementable
|
// FIXME: not yet implementable
|
||||||
// void write_on(DebugInfoWriteStream* stream);
|
// void write_on(DebugInfoWriteStream* stream);
|
||||||
@ -50,5 +53,8 @@ public class MonitorValue {
|
|||||||
tty.print(",");
|
tty.print(",");
|
||||||
basicLock().printOn(tty);
|
basicLock().printOn(tty);
|
||||||
tty.print("}");
|
tty.print("}");
|
||||||
|
if (eliminated) {
|
||||||
|
tty.print(" (eliminated)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -27,8 +27,10 @@ package sun.jvm.hotspot.code;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
import sun.jvm.hotspot.oops.*;
|
import sun.jvm.hotspot.oops.*;
|
||||||
import sun.jvm.hotspot.runtime.*;
|
import sun.jvm.hotspot.runtime.*;
|
||||||
|
import sun.jvm.hotspot.utilities.*;
|
||||||
|
|
||||||
/** ScopeDescs contain the information that makes source-level
|
/** ScopeDescs contain the information that makes source-level
|
||||||
debugging of nmethods possible; each scopeDesc describes a method
|
debugging of nmethods possible; each scopeDesc describes a method
|
||||||
@ -45,10 +47,31 @@ public class ScopeDesc {
|
|||||||
private int localsDecodeOffset;
|
private int localsDecodeOffset;
|
||||||
private int expressionsDecodeOffset;
|
private int expressionsDecodeOffset;
|
||||||
private int monitorsDecodeOffset;
|
private int monitorsDecodeOffset;
|
||||||
|
/** Scalar replaced bjects pool */
|
||||||
|
private List objects; // ArrayList<ScopeValue>
|
||||||
|
|
||||||
|
|
||||||
public ScopeDesc(NMethod code, int decodeOffset) {
|
public ScopeDesc(NMethod code, int decodeOffset) {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.decodeOffset = decodeOffset;
|
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
|
// Decode header
|
||||||
DebugInfoReadStream stream = streamAt(decodeOffset);
|
DebugInfoReadStream stream = streamAt(decodeOffset);
|
||||||
@ -81,6 +104,11 @@ public class ScopeDesc {
|
|||||||
return decodeMonitorValues(monitorsDecodeOffset);
|
return decodeMonitorValues(monitorsDecodeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns a List<MonitorValue> */
|
||||||
|
public List getObjects() {
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
/** Stack walking. Returns null if this is the outermost scope. */
|
/** Stack walking. Returns null if this is the outermost scope. */
|
||||||
public ScopeDesc sender() {
|
public ScopeDesc sender() {
|
||||||
if (isTop()) {
|
if (isTop()) {
|
||||||
@ -131,7 +159,7 @@ public class ScopeDesc {
|
|||||||
//
|
//
|
||||||
|
|
||||||
private DebugInfoReadStream streamAt(int decodeOffset) {
|
private DebugInfoReadStream streamAt(int decodeOffset) {
|
||||||
return new DebugInfoReadStream(code, decodeOffset);
|
return new DebugInfoReadStream(code, decodeOffset, objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a List<ScopeValue> or null if no values were present */
|
/** Returns a List<ScopeValue> or null if no values were present */
|
||||||
@ -161,4 +189,22 @@ public class ScopeDesc {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns a List<ObjectValue> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,12 +49,15 @@ public abstract class ScopeValue {
|
|||||||
static final int CONSTANT_OOP_CODE = 2;
|
static final int CONSTANT_OOP_CODE = 2;
|
||||||
static final int CONSTANT_LONG_CODE = 3;
|
static final int CONSTANT_LONG_CODE = 3;
|
||||||
static final int CONSTANT_DOUBLE_CODE = 4;
|
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 isLocation() { return false; }
|
||||||
public boolean isConstantInt() { return false; }
|
public boolean isConstantInt() { return false; }
|
||||||
public boolean isConstantDouble() { return false; }
|
public boolean isConstantDouble() { return false; }
|
||||||
public boolean isConstantLong() { return false; }
|
public boolean isConstantLong() { return false; }
|
||||||
public boolean isConstantOop() { return false; }
|
public boolean isConstantOop() { return false; }
|
||||||
|
public boolean isObject() { return false; }
|
||||||
|
|
||||||
public static ScopeValue readFrom(DebugInfoReadStream stream) {
|
public static ScopeValue readFrom(DebugInfoReadStream stream) {
|
||||||
switch (stream.readInt()) {
|
switch (stream.readInt()) {
|
||||||
@ -68,6 +71,10 @@ public abstract class ScopeValue {
|
|||||||
return new ConstantLongValue(stream);
|
return new ConstantLongValue(stream);
|
||||||
case CONSTANT_DOUBLE_CODE:
|
case CONSTANT_DOUBLE_CODE:
|
||||||
return new ConstantDoubleValue(stream);
|
return new ConstantDoubleValue(stream);
|
||||||
|
case CONSTANT_OBJECT_CODE:
|
||||||
|
return stream.readObjectValue();
|
||||||
|
case CONSTANT_OBJECT_ID_CODE:
|
||||||
|
return stream.getCachedObject();
|
||||||
default:
|
default:
|
||||||
Assert.that(false, "should not reach here");
|
Assert.that(false, "should not reach here");
|
||||||
return null;
|
return null;
|
||||||
|
@ -249,6 +249,7 @@ public class ObjectReferenceImpl extends ValueImpl implements ObjectReference {
|
|||||||
OopHandle givenHandle = obj.getHandle();
|
OopHandle givenHandle = obj.getHandle();
|
||||||
for (Iterator itr = monitors.iterator(); itr.hasNext();) {
|
for (Iterator itr = monitors.iterator(); itr.hasNext();) {
|
||||||
MonitorInfo mi = (MonitorInfo) itr.next();
|
MonitorInfo mi = (MonitorInfo) itr.next();
|
||||||
|
if (mi.eliminated() && frame.isCompiledFrame()) continue; // skip eliminated monitor
|
||||||
if (givenHandle.equals(mi.owner())) {
|
if (givenHandle.equals(mi.owner())) {
|
||||||
res++;
|
res++;
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,9 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
|
|||||||
List frameMonitors = frame.getMonitors(); // List<MonitorInfo>
|
List frameMonitors = frame.getMonitors(); // List<MonitorInfo>
|
||||||
for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
|
for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
|
||||||
sun.jvm.hotspot.runtime.MonitorInfo mi = (sun.jvm.hotspot.runtime.MonitorInfo) miItr.next();
|
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();
|
OopHandle obj = mi.owner();
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
// this monitor doesn't have an owning object so skip it
|
// this monitor doesn't have an owning object so skip it
|
||||||
|
@ -131,8 +131,18 @@ public class CompiledVFrame extends JavaVFrame {
|
|||||||
List result = new ArrayList(monitors.size());
|
List result = new ArrayList(monitors.size());
|
||||||
for (int i = 0; i < monitors.size(); i++) {
|
for (int i = 0; i < monitors.size(); i++) {
|
||||||
MonitorValue mv = (MonitorValue) monitors.get(i);
|
MonitorValue mv = (MonitorValue) monitors.get(i);
|
||||||
StackValue ownerSV = createStackValue(mv.owner()); // it is an oop
|
ScopeValue ov = mv.owner();
|
||||||
result.add(new MonitorInfo(ownerSV.getObject(), resolveMonitorLock(mv.basicLock())));
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
@ -212,12 +222,12 @@ public class CompiledVFrame extends JavaVFrame {
|
|||||||
// long or is unused. He always saves a long. Here we know
|
// 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
|
// a long was saved, but we only want an narrow oop back. Narrow the
|
||||||
// saved long to the narrow oop that the JVM wants.
|
// 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 {
|
} else {
|
||||||
return new StackValue(valueAddr.getCompOopHandleAt(0));
|
return new StackValue(valueAddr.getCompOopHandleAt(0), 0);
|
||||||
}
|
}
|
||||||
} else if( loc.holdsOop() ) { // Holds an oop?
|
} else if( loc.holdsOop() ) { // Holds an oop?
|
||||||
return new StackValue(valueAddr.getOopHandleAt(0));
|
return new StackValue(valueAddr.getOopHandleAt(0), 0);
|
||||||
} else if( loc.holdsDouble() ) {
|
} else if( loc.holdsDouble() ) {
|
||||||
// Double value in a single stack slot
|
// Double value in a single stack slot
|
||||||
return new StackValue(valueAddr.getJIntAt(0) & 0xFFFFFFFF);
|
return new StackValue(valueAddr.getJIntAt(0) & 0xFFFFFFFF);
|
||||||
@ -277,7 +287,7 @@ public class CompiledVFrame extends JavaVFrame {
|
|||||||
return new StackValue(((ConstantIntValue) sv).getValue() & 0xFFFFFFFF);
|
return new StackValue(((ConstantIntValue) sv).getValue() & 0xFFFFFFFF);
|
||||||
} else if (sv.isConstantOop()) {
|
} else if (sv.isConstantOop()) {
|
||||||
// constant oop
|
// constant oop
|
||||||
return new StackValue(((ConstantOopReadValue) sv).getValue());
|
return new StackValue(((ConstantOopReadValue) sv).getValue(), 0);
|
||||||
} else if (sv.isConstantDouble()) {
|
} else if (sv.isConstantDouble()) {
|
||||||
// Constant double in a single stack slot
|
// Constant double in a single stack slot
|
||||||
double d = ((ConstantDoubleValue) sv).getValue();
|
double d = ((ConstantDoubleValue) sv).getValue();
|
||||||
@ -285,6 +295,9 @@ public class CompiledVFrame extends JavaVFrame {
|
|||||||
} else if (VM.getVM().isLP64() && sv.isConstantLong()) {
|
} else if (VM.getVM().isLP64() && sv.isConstantLong()) {
|
||||||
// Constant long in a single stack slot
|
// Constant long in a single stack slot
|
||||||
return new StackValue(((ConstantLongValue) sv).getValue() & 0xFFFFFFFF);
|
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
|
// Unknown ScopeValue type
|
||||||
|
@ -61,7 +61,7 @@ public class InterpretedVFrame extends JavaVFrame {
|
|||||||
StackValue sv;
|
StackValue sv;
|
||||||
if (oopMask.isOop(i)) {
|
if (oopMask.isOop(i)) {
|
||||||
// oop value
|
// oop value
|
||||||
sv = new StackValue(addr.getOopHandleAt(0));
|
sv = new StackValue(addr.getOopHandleAt(0), 0);
|
||||||
} else {
|
} else {
|
||||||
// integer
|
// integer
|
||||||
// Fetch a signed integer the size of a stack slot
|
// Fetch a signed integer the size of a stack slot
|
||||||
@ -95,7 +95,7 @@ public class InterpretedVFrame extends JavaVFrame {
|
|||||||
StackValue sv;
|
StackValue sv;
|
||||||
if (oopMask.isOop(i + nofLocals)) {
|
if (oopMask.isOop(i + nofLocals)) {
|
||||||
// oop value
|
// oop value
|
||||||
sv = new StackValue(addr.getOopHandleAt(0));
|
sv = new StackValue(addr.getOopHandleAt(0), 0);
|
||||||
} else {
|
} else {
|
||||||
// integer
|
// integer
|
||||||
// Fetch a signed integer the size of a stack slot
|
// Fetch a signed integer the size of a stack slot
|
||||||
@ -113,7 +113,7 @@ public class InterpretedVFrame extends JavaVFrame {
|
|||||||
for (BasicObjectLock current = getFrame().interpreterFrameMonitorEnd();
|
for (BasicObjectLock current = getFrame().interpreterFrameMonitorEnd();
|
||||||
current.address().lessThan(getFrame().interpreterFrameMonitorBegin().address());
|
current.address().lessThan(getFrame().interpreterFrameMonitorBegin().address());
|
||||||
current = getFrame().nextMonitorInInterpreterFrame(current)) {
|
current = getFrame().nextMonitorInInterpreterFrame(current)) {
|
||||||
result.add(new MonitorInfo(current.obj(), current.lock()));
|
result.add(new MonitorInfo(current.obj(), current.lock(), false, false));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -25,16 +25,39 @@
|
|||||||
package sun.jvm.hotspot.runtime;
|
package sun.jvm.hotspot.runtime;
|
||||||
|
|
||||||
import sun.jvm.hotspot.debugger.*;
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.utilities.*;
|
||||||
|
|
||||||
public class MonitorInfo {
|
public class MonitorInfo {
|
||||||
private OopHandle owner;
|
private OopHandle owner;
|
||||||
private BasicLock lock;
|
private BasicLock lock;
|
||||||
|
private OopHandle ownerKlass;
|
||||||
|
private boolean eliminated;
|
||||||
|
private boolean ownerIsScalarReplaced;
|
||||||
|
|
||||||
public MonitorInfo(OopHandle owner, BasicLock lock) {
|
public MonitorInfo(OopHandle owner, BasicLock lock, boolean eliminated, boolean ownerIsScalarReplaced) {
|
||||||
this.owner = owner;
|
if (!ownerIsScalarReplaced) {
|
||||||
this.lock = lock;
|
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 BasicLock lock() { return lock; }
|
||||||
|
public boolean eliminated() { return eliminated; }
|
||||||
|
public boolean ownerIsScalarReplaced() { return ownerIsScalarReplaced; }
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,11 @@ public class StackValue {
|
|||||||
type = BasicType.getTConflict();
|
type = BasicType.getTConflict();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StackValue(OopHandle h) {
|
public StackValue(OopHandle h, long scalar_replaced) {
|
||||||
handleValue = h;
|
handleValue = h;
|
||||||
type = BasicType.getTObject();
|
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) {
|
public StackValue(long i) {
|
||||||
@ -59,6 +61,13 @@ public class StackValue {
|
|||||||
return handleValue;
|
return handleValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean objIsScalarReplaced() {
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(type == BasicType.getTObject(), "type check");
|
||||||
|
}
|
||||||
|
return integerValue != 0;
|
||||||
|
}
|
||||||
|
|
||||||
public long getInteger() {
|
public long getInteger() {
|
||||||
if (Assert.ASSERTS_ENABLED) {
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
Assert.that(type == BasicType.getTInt(), "type check");
|
Assert.that(type == BasicType.getTInt(), "type check");
|
||||||
|
@ -135,6 +135,10 @@ public class JSJavaThread extends JSJavaInstance {
|
|||||||
List frameMonitors = frame.getMonitors(); // List<MonitorInfo>
|
List frameMonitors = frame.getMonitors(); // List<MonitorInfo>
|
||||||
for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
|
for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
|
||||||
MonitorInfo mi = (MonitorInfo) miItr.next();
|
MonitorInfo mi = (MonitorInfo) miItr.next();
|
||||||
|
|
||||||
|
if (mi.eliminated() && frame.isCompiledFrame()) {
|
||||||
|
continue; // skip eliminated monitor
|
||||||
|
}
|
||||||
OopHandle obj = mi.owner();
|
OopHandle obj = mi.owner();
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
// this monitor doesn't have an owning object so skip it
|
// this monitor doesn't have an owning object so skip it
|
||||||
|
@ -104,7 +104,9 @@ void C2Compiler::compile_method(ciEnv* env,
|
|||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
bool subsume_loads = true;
|
bool subsume_loads = true;
|
||||||
bool do_escape_analysis = DoEscapeAnalysis;
|
bool do_escape_analysis = DoEscapeAnalysis &&
|
||||||
|
!(env->jvmti_can_hotswap_or_post_breakpoint() ||
|
||||||
|
env->jvmti_can_examine_or_deopt_anywhere());
|
||||||
while (!env->failing()) {
|
while (!env->failing()) {
|
||||||
// Attempt to compile while subsuming loads into machine instructions.
|
// Attempt to compile while subsuming loads into machine instructions.
|
||||||
Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis);
|
Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis);
|
||||||
|
@ -606,6 +606,7 @@ JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) {
|
|||||||
if (!mons->is_empty()) {
|
if (!mons->is_empty()) {
|
||||||
for (int i = 0; i < mons->length(); i++) {
|
for (int i = 0; i < mons->length(); i++) {
|
||||||
MonitorInfo *mi = mons->at(i);
|
MonitorInfo *mi = mons->at(i);
|
||||||
|
if (mi->owner_is_scalar_replaced()) continue;
|
||||||
|
|
||||||
// see if owner of the monitor is our object
|
// see if owner of the monitor is our object
|
||||||
if (mi->owner() != NULL && mi->owner() == hobj()) {
|
if (mi->owner() != NULL && mi->owner() == hobj()) {
|
||||||
@ -726,6 +727,8 @@ JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread
|
|||||||
for (int i = 0; i < mons->length(); i++) {
|
for (int i = 0; i < mons->length(); i++) {
|
||||||
MonitorInfo *mi = mons->at(i);
|
MonitorInfo *mi = mons->at(i);
|
||||||
|
|
||||||
|
if (mi->owner_is_scalar_replaced()) continue;
|
||||||
|
|
||||||
oop obj = mi->owner();
|
oop obj = mi->owner();
|
||||||
if (obj == NULL) {
|
if (obj == NULL) {
|
||||||
// this monitor doesn't have an owning object so skip it
|
// this monitor doesn't have an owning object so skip it
|
||||||
|
@ -121,6 +121,7 @@ static GrowableArray<MonitorInfo*>* get_or_compute_monitor_info(JavaThread* thre
|
|||||||
// Walk monitors youngest to oldest
|
// Walk monitors youngest to oldest
|
||||||
for (int i = len - 1; i >= 0; i--) {
|
for (int i = len - 1; i >= 0; i--) {
|
||||||
MonitorInfo* mon_info = monitors->at(i);
|
MonitorInfo* mon_info = monitors->at(i);
|
||||||
|
if (mon_info->owner_is_scalar_replaced()) continue;
|
||||||
oop owner = mon_info->owner();
|
oop owner = mon_info->owner();
|
||||||
if (owner != NULL) {
|
if (owner != NULL) {
|
||||||
info->append(mon_info);
|
info->append(mon_info);
|
||||||
@ -694,6 +695,7 @@ void BiasedLocking::preserve_marks() {
|
|||||||
// Walk monitors youngest to oldest
|
// Walk monitors youngest to oldest
|
||||||
for (int i = len - 1; i >= 0; i--) {
|
for (int i = len - 1; i >= 0; i--) {
|
||||||
MonitorInfo* mon_info = monitors->at(i);
|
MonitorInfo* mon_info = monitors->at(i);
|
||||||
|
if (mon_info->owner_is_scalar_replaced()) continue;
|
||||||
oop owner = mon_info->owner();
|
oop owner = mon_info->owner();
|
||||||
if (owner != NULL) {
|
if (owner != NULL) {
|
||||||
markOop mark = owner->mark();
|
markOop mark = owner->mark();
|
||||||
|
@ -933,7 +933,7 @@ static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects
|
|||||||
GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
|
GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
|
||||||
for (int i = 0; i < monitors->length(); i++) {
|
for (int i = 0; i < monitors->length(); i++) {
|
||||||
MonitorInfo* mon_info = monitors->at(i);
|
MonitorInfo* mon_info = monitors->at(i);
|
||||||
if (mon_info->owner() != NULL && !mon_info->eliminated()) {
|
if (!mon_info->eliminated() && mon_info->owner() != NULL) {
|
||||||
objects_to_revoke->append(Handle(mon_info->owner()));
|
objects_to_revoke->append(Handle(mon_info->owner()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,8 +146,9 @@ StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* r
|
|||||||
value.jl = ((ConstantLongValue *)sv)->value();
|
value.jl = ((ConstantLongValue *)sv)->value();
|
||||||
return new StackValue(value.p);
|
return new StackValue(value.p);
|
||||||
#endif
|
#endif
|
||||||
} else if (sv->is_object()) {
|
} else if (sv->is_object()) { // Scalar replaced object in compiled frame
|
||||||
return new StackValue(((ObjectValue *)sv)->value());
|
Handle ov = ((ObjectValue *)sv)->value();
|
||||||
|
return new StackValue(ov, (ov.is_null()) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unknown ScopeValue type
|
// Unknown ScopeValue type
|
||||||
|
@ -34,9 +34,11 @@ class StackValue : public ResourceObj {
|
|||||||
_i = value;
|
_i = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
StackValue(Handle value) {
|
StackValue(Handle value, intptr_t scalar_replaced = 0) {
|
||||||
_type = T_OBJECT;
|
_type = T_OBJECT;
|
||||||
|
_i = scalar_replaced;
|
||||||
_o = value;
|
_o = value;
|
||||||
|
assert(_i == 0 || _o.is_null(), "not null object should not be marked as scalar replaced");
|
||||||
}
|
}
|
||||||
|
|
||||||
StackValue() {
|
StackValue() {
|
||||||
@ -56,6 +58,11 @@ class StackValue : public ResourceObj {
|
|||||||
return _o;
|
return _o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool obj_is_scalar_replaced() const {
|
||||||
|
assert(type() == T_OBJECT, "type check");
|
||||||
|
return _i != 0;
|
||||||
|
}
|
||||||
|
|
||||||
void set_obj(Handle value) {
|
void set_obj(Handle value) {
|
||||||
assert(type() == T_OBJECT, "type check");
|
assert(type() == T_OBJECT, "type check");
|
||||||
_o = value;
|
_o = value;
|
||||||
|
@ -106,6 +106,7 @@ GrowableArray<MonitorInfo*>* javaVFrame::locked_monitors() {
|
|||||||
|
|
||||||
for (int index = (mons->length()-1); index >= 0; index--) {
|
for (int index = (mons->length()-1); index >= 0; index--) {
|
||||||
MonitorInfo* monitor = mons->at(index);
|
MonitorInfo* monitor = mons->at(index);
|
||||||
|
if (monitor->eliminated() && is_compiled_frame()) continue; // skip eliminated monitor
|
||||||
oop obj = monitor->owner();
|
oop obj = monitor->owner();
|
||||||
if (obj == NULL) continue; // skip unowned monitor
|
if (obj == NULL) continue; // skip unowned monitor
|
||||||
//
|
//
|
||||||
@ -162,6 +163,18 @@ void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
|
|||||||
bool found_first_monitor = false;
|
bool found_first_monitor = false;
|
||||||
for (int index = (mons->length()-1); index >= 0; index--) {
|
for (int index = (mons->length()-1); index >= 0; index--) {
|
||||||
MonitorInfo* monitor = mons->at(index);
|
MonitorInfo* monitor = mons->at(index);
|
||||||
|
if (monitor->eliminated() && is_compiled_frame()) { // Eliminated in compiled code
|
||||||
|
if (monitor->owner_is_scalar_replaced()) {
|
||||||
|
Klass* k = Klass::cast(monitor->owner_klass());
|
||||||
|
st->print("\t- eliminated <owner is scalar replaced> (a %s)", k->external_name());
|
||||||
|
} else {
|
||||||
|
oop obj = monitor->owner();
|
||||||
|
if (obj != NULL) {
|
||||||
|
print_locked_object_class_name(st, obj, "eliminated");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (monitor->owner() != NULL) {
|
if (monitor->owner() != NULL) {
|
||||||
|
|
||||||
// First, assume we have the monitor locked. If we haven't found an
|
// First, assume we have the monitor locked. If we haven't found an
|
||||||
@ -171,11 +184,11 @@ void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
|
|||||||
|
|
||||||
const char *lock_state = "locked"; // assume we have the monitor locked
|
const char *lock_state = "locked"; // assume we have the monitor locked
|
||||||
if (!found_first_monitor && frame_count == 0) {
|
if (!found_first_monitor && frame_count == 0) {
|
||||||
markOop mark = monitor->owner()->mark();
|
markOop mark = monitor->owner()->mark();
|
||||||
if (mark->has_monitor() &&
|
if (mark->has_monitor() &&
|
||||||
mark->monitor() == thread()->current_pending_monitor()) {
|
mark->monitor() == thread()->current_pending_monitor()) {
|
||||||
lock_state = "waiting to lock";
|
lock_state = "waiting to lock";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
found_first_monitor = true;
|
found_first_monitor = true;
|
||||||
@ -206,7 +219,7 @@ GrowableArray<MonitorInfo*>* interpretedVFrame::monitors() const {
|
|||||||
for (BasicObjectLock* current = (fr().previous_monitor_in_interpreter_frame(fr().interpreter_frame_monitor_begin()));
|
for (BasicObjectLock* current = (fr().previous_monitor_in_interpreter_frame(fr().interpreter_frame_monitor_begin()));
|
||||||
current >= fr().interpreter_frame_monitor_end();
|
current >= fr().interpreter_frame_monitor_end();
|
||||||
current = fr().previous_monitor_in_interpreter_frame(current)) {
|
current = fr().previous_monitor_in_interpreter_frame(current)) {
|
||||||
result->push(new MonitorInfo(current->obj(), current->lock(), false));
|
result->push(new MonitorInfo(current->obj(), current->lock(), false, false));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -531,8 +544,18 @@ void javaVFrame::print() {
|
|||||||
tty->print_cr("\tmonitor list:");
|
tty->print_cr("\tmonitor list:");
|
||||||
for (int index = (list->length()-1); index >= 0; index--) {
|
for (int index = (list->length()-1); index >= 0; index--) {
|
||||||
MonitorInfo* monitor = list->at(index);
|
MonitorInfo* monitor = list->at(index);
|
||||||
tty->print("\t obj\t"); monitor->owner()->print_value();
|
tty->print("\t obj\t");
|
||||||
tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner());
|
if (monitor->owner_is_scalar_replaced()) {
|
||||||
|
Klass* k = Klass::cast(monitor->owner_klass());
|
||||||
|
tty->print("( is scalar replaced %s)", k->external_name());
|
||||||
|
} else if (monitor->owner() == NULL) {
|
||||||
|
tty->print("( null )");
|
||||||
|
} else {
|
||||||
|
monitor->owner()->print_value();
|
||||||
|
tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner());
|
||||||
|
}
|
||||||
|
if (monitor->eliminated() && is_compiled_frame())
|
||||||
|
tty->print(" ( lock is eliminated )");
|
||||||
tty->cr();
|
tty->cr();
|
||||||
tty->print("\t ");
|
tty->print("\t ");
|
||||||
monitor->lock()->print_on(tty);
|
monitor->lock()->print_on(tty);
|
||||||
|
@ -230,18 +230,36 @@ class MonitorInfo : public ResourceObj {
|
|||||||
private:
|
private:
|
||||||
oop _owner; // the object owning the monitor
|
oop _owner; // the object owning the monitor
|
||||||
BasicLock* _lock;
|
BasicLock* _lock;
|
||||||
|
oop _owner_klass; // klass if owner was scalar replaced
|
||||||
bool _eliminated;
|
bool _eliminated;
|
||||||
|
bool _owner_is_scalar_replaced;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
MonitorInfo(oop owner, BasicLock* lock, bool eliminated) {
|
MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced) {
|
||||||
_owner = owner;
|
if (!owner_is_scalar_replaced) {
|
||||||
|
_owner = owner;
|
||||||
|
_owner_klass = NULL;
|
||||||
|
} else {
|
||||||
|
assert(eliminated, "monitor should be eliminated for scalar replaced object");
|
||||||
|
_owner = NULL;
|
||||||
|
_owner_klass = owner;
|
||||||
|
}
|
||||||
_lock = lock;
|
_lock = lock;
|
||||||
_eliminated = eliminated;
|
_eliminated = eliminated;
|
||||||
|
_owner_is_scalar_replaced = owner_is_scalar_replaced;
|
||||||
}
|
}
|
||||||
// Accessors
|
// Accessors
|
||||||
oop owner() const { return _owner; }
|
oop owner() const {
|
||||||
|
assert(!_owner_is_scalar_replaced, "should not be called for scalar replaced object");
|
||||||
|
return _owner;
|
||||||
|
}
|
||||||
|
klassOop owner_klass() const {
|
||||||
|
assert(_owner_is_scalar_replaced, "should not be called for not scalar replaced object");
|
||||||
|
return (klassOop)_owner_klass;
|
||||||
|
}
|
||||||
BasicLock* lock() const { return _lock; }
|
BasicLock* lock() const { return _lock; }
|
||||||
bool eliminated() const { return _eliminated; }
|
bool eliminated() const { return _eliminated; }
|
||||||
|
bool owner_is_scalar_replaced() const { return _owner_is_scalar_replaced; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class vframeStreamCommon : StackObj {
|
class vframeStreamCommon : StackObj {
|
||||||
|
@ -61,6 +61,7 @@ void vframeArrayElement::fill_in(compiledVFrame* vf) {
|
|||||||
// Migrate the BasicLocks from the stack to the monitor chunk
|
// Migrate the BasicLocks from the stack to the monitor chunk
|
||||||
for (index = 0; index < list->length(); index++) {
|
for (index = 0; index < list->length(); index++) {
|
||||||
MonitorInfo* monitor = list->at(index);
|
MonitorInfo* monitor = list->at(index);
|
||||||
|
assert(!monitor->owner_is_scalar_replaced(), "object should be reallocated already");
|
||||||
assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
|
assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
|
||||||
BasicObjectLock* dest = _monitors->at(index);
|
BasicObjectLock* dest = _monitors->at(index);
|
||||||
dest->set_obj(monitor->owner());
|
dest->set_obj(monitor->owner());
|
||||||
@ -89,6 +90,7 @@ void vframeArrayElement::fill_in(compiledVFrame* vf) {
|
|||||||
StackValue* value = locs->at(index);
|
StackValue* value = locs->at(index);
|
||||||
switch(value->type()) {
|
switch(value->type()) {
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
|
assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
|
||||||
// preserve object type
|
// preserve object type
|
||||||
_locals->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT ));
|
_locals->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT ));
|
||||||
break;
|
break;
|
||||||
@ -113,6 +115,7 @@ void vframeArrayElement::fill_in(compiledVFrame* vf) {
|
|||||||
StackValue* value = exprs->at(index);
|
StackValue* value = exprs->at(index);
|
||||||
switch(value->type()) {
|
switch(value->type()) {
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
|
assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
|
||||||
// preserve object type
|
// preserve object type
|
||||||
_expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT ));
|
_expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT ));
|
||||||
break;
|
break;
|
||||||
|
@ -190,7 +190,7 @@ GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
|
|||||||
// Casting away const
|
// Casting away const
|
||||||
frame& fr = (frame&) _fr;
|
frame& fr = (frame&) _fr;
|
||||||
MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm),
|
MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm),
|
||||||
fr.compiled_synchronized_native_monitor(nm), false);
|
fr.compiled_synchronized_native_monitor(nm), false, false);
|
||||||
monitors->push(info);
|
monitors->push(info);
|
||||||
return monitors;
|
return monitors;
|
||||||
}
|
}
|
||||||
@ -201,8 +201,20 @@ GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
|
|||||||
GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(monitors->length());
|
GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(monitors->length());
|
||||||
for (int index = 0; index < monitors->length(); index++) {
|
for (int index = 0; index < monitors->length(); index++) {
|
||||||
MonitorValue* mv = monitors->at(index);
|
MonitorValue* mv = monitors->at(index);
|
||||||
StackValue *owner_sv = create_stack_value(mv->owner()); // it is an oop
|
ScopeValue* ov = mv->owner();
|
||||||
result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()), mv->eliminated()));
|
StackValue *owner_sv = create_stack_value(ov); // it is an oop
|
||||||
|
if (ov->is_object() && owner_sv->obj_is_scalar_replaced()) { // The owner object was scalar replaced
|
||||||
|
assert(mv->eliminated(), "monitor should be eliminated for scalar replaced object");
|
||||||
|
// Put klass for scalar replaced object.
|
||||||
|
ScopeValue* kv = ((ObjectValue *)ov)->klass();
|
||||||
|
assert(kv->is_constant_oop(), "klass should be oop constant for scalar replaced object");
|
||||||
|
KlassHandle k(((ConstantOopReadValue*)kv)->value()());
|
||||||
|
result->push(new MonitorInfo(k->as_klassOop(), resolve_monitor_lock(mv->basic_lock()),
|
||||||
|
mv->eliminated(), true));
|
||||||
|
} else {
|
||||||
|
result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()),
|
||||||
|
mv->eliminated(), false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user