package sun.jvm.hotspot.runtime;
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.debugger.*;
public abstract class JavaVFrame extends VFrame {
private static final String ADDRESS_FORMAT = VM.getVM().isLP64() ? "0x%016x"
: "0x%08x";
public abstract Method getMethod();
public abstract int getBCI();
public abstract StackValueCollection getLocals();
public abstract StackValueCollection getExpressions();
public abstract List<MonitorInfo> getMonitors();
public boolean isJavaFrame() { return true; }
JavaVFrame(Frame fr, RegisterMap regMap, JavaThread thread) {
super(fr, regMap, thread);
}
public void printLockedObjectClassName(PrintStream tty,
OopHandle hobj, String lockState) {
if (hobj.asLongValue() != 0L) {
tty.format("\t- %s <" + ADDRESS_FORMAT + "> ",
lockState, hobj.asLongValue());
Klass klass = Oop.getKlassForOopHandle(hobj);
String klassName = klass.getName().asString();
tty.print("(a ");
if (klassName.equals("java/lang/Class")) {
Oop obj = VM.getVM().getObjectHeap().newOop(hobj);
klassName = java_lang_Class.asExternalName(obj);
tty.print("java.lang.Class for ");
}
tty.println(klassName.replace('/', '.') + ")");
}
}
private String identifyLockState(MonitorInfo monitor, String waitingState) {
Mark mark = new Mark(monitor.owner());
if (mark.hasMonitor() &&
(
mark.monitor().equals(thread.getCurrentPendingMonitor()) ||
!mark.monitor().isEntered(thread)
)) {
return waitingState;
}
return "locked";
}
public void printLockInfo(PrintStream tty, int frameCount) {
if (frameCount == 0) {
if (getMethod().getName().asString().equals("wait") &&
getMethod().getMethodHolder().getName().asString().equals("java/lang/Object")) {
String waitState = "waiting on";
StackValueCollection locs = getLocals();
if (!locs.isEmpty()) {
StackValue sv = locs.get(0);
if (sv.getType() == BasicType.getTObject()) {
OopHandle o = sv.getObject();
if (OopUtilities.threadOopGetThreadStatus(thread.getThreadObj()) == OopUtilities.THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER) {
waitState = "waiting to re-lock in wait()";
}
printLockedObjectClassName(tty, o, waitState);
}
} else {
tty.println("\t- " + waitState + " <no object reference available>");
}
} else if (thread.getCurrentParkBlocker() != null) {
Oop obj = thread.getCurrentParkBlocker();
Klass k = obj.getKlass();
tty.format("\t- parking to wait for <" + ADDRESS_FORMAT + "> (a %s)",
obj.getHandle().asLongValue(), k.getName().asString());
tty.println();
}
}
List<MonitorInfo> mons = getMonitors();
if (!mons.isEmpty()) {
boolean foundFirstMonitor = false;
for (int index = mons.size() - 1; index >= 0; index--) {
MonitorInfo monitor = mons.get(index);
if (monitor.eliminated() && isCompiledFrame()) {
if (monitor.ownerIsScalarReplaced()) {
Klass k = Oop.getKlassForOopHandle(monitor.ownerKlass());
tty.println("\t- eliminated <owner is scalar replaced> (a " + k.getName().asString() + ")");
} else if (monitor.owner() != null) {
printLockedObjectClassName(tty, monitor.owner(), "eliminated");
}
continue;
}
if (monitor.owner() != null) {
String lockState = "locked";
if (!foundFirstMonitor && frameCount == 0) {
lockState = identifyLockState(monitor, "waiting to lock");
}
printLockedObjectClassName(tty, monitor.owner(), lockState);
foundFirstMonitor = true;
}
}
}
}
public void print() {
printOn(System.out);
}
public void printOn(PrintStream tty) {
super.printOn(tty);
tty.print("\t");
getMethod().printValueOn(tty);
tty.println();
tty.println("\tbci:\t" + getBCI());
printStackValuesOn(tty, "locals", getLocals());
printStackValuesOn(tty, "expressions", getExpressions());
}
public void printActivation(int index) {
printActivationOn(System.out, index);
}
public void printActivationOn(PrintStream tty, int index) {
tty.print(index + " - ");
printValueOn(tty);
tty.println();
if (VM.getVM().wizardMode()) {
printOn(tty);
tty.println();
}
}
public void verify() {
}
public boolean equals(Object o) {
if (o == null || !(o instanceof JavaVFrame)) {
return false;
}
JavaVFrame other = (JavaVFrame) o;
if (!getMethod().equals(other.getMethod())) {
return false;
}
if (getBCI() != other.getBCI()) {
return false;
}
if (! getFrame().equals(other.getFrame())) {
return false;
}
return true;
}
public int hashCode() {
return getMethod().hashCode() ^ getBCI() ^ getFrame().hashCode();
}
public boolean structuralCompare(JavaVFrame other) {
if (!getMethod().equals(other.getMethod())) {
return false;
}
if (getBCI() != other.getBCI()) {
return false;
}
StackValueCollection locs = getLocals();
StackValueCollection otherLocs = other.getLocals();
if (Assert.ASSERTS_ENABLED) {
Assert.that(locs.size() == otherLocs.size(), "sanity check");
}
for (int i = 0; i < locs.size(); i++) {
if ( isCompiledFrame() && (locs.get(i)).getType() == BasicType.getTConflict()) continue;
if (other.isCompiledFrame() && (otherLocs.get(i)).getType() == BasicType.getTConflict()) continue;
if (!locs.get(i).equals(otherLocs.get(i))) {
return false;
}
}
StackValueCollection exprs = getExpressions();
StackValueCollection otherExprs = other.getExpressions();
if (Assert.ASSERTS_ENABLED) {
Assert.that(exprs.size() == otherExprs.size(), "sanity check");
}
for (int i = 0; i < exprs.size(); i++) {
if (!exprs.get(i).equals(otherExprs.get(i))) {
return false;
}
}
return true;
}
private void printStackValuesOn(PrintStream tty, String title, StackValueCollection values) {
if (values.isEmpty()) {
return;
}
tty.println("\t" + title + ":");
for (int index = 0; index < values.size(); index++) {
tty.print("\t" + index + "\t");
values.get(index).printOn(tty);
tty.println();
}
}
}