blob: a45cbc3640c450a0d215189e8d6a518d250788aa [file] [log] [blame]
/*
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime;
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
public abstract class JavaVFrame extends VFrame {
/** JVM state */
public abstract Method getMethod();
public abstract int getBCI();
public abstract StackValueCollection getLocals();
public abstract StackValueCollection getExpressions();
public abstract List getMonitors(); // List<MonitorInfo>
/** Test operation */
public boolean isJavaFrame() { return true; }
/** Package-internal constructor */
JavaVFrame(Frame fr, RegisterMap regMap, JavaThread thread) {
super(fr, regMap, thread);
}
/** Get monitor (if any) that this JavaVFrame is trying to enter */
// FIXME: not yet implemented
// public Address getPendingMonitor(int frameCount);
/** Printing used during stack dumps */
// FIXME: not yet implemented
// void print_lock_info(int frame_count);
/** Printing operations */
//
// FIXME: implement visitor pattern for traversing vframe contents?
//
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());
// List<MonitorInfo>
// FIXME: not yet implemented
// List list = getMonitors();
// if (list.isEmpty()) {
// return;
// }
// for (int index = 0; index < list.size(); index++) {
// MonitorInfo monitor = (MonitorInfo) list.get(index);
// tty.print("\t obj\t");
// monitor.getOwner().printValueOn(tty);
// tty.println();
// tty.print("\t ");
// monitor.lock().printOn(tty);
// tty.println();
// }
}
public void printActivation(int index) {
printActivationOn(System.out, index);
}
public void printActivationOn(PrintStream tty, int index) {
// frame number and method
tty.print(index + " - ");
printValueOn(tty);
tty.println();
if (VM.getVM().wizardMode()) {
printOn(tty);
tty.println();
}
}
/** Verification operations */
public void verify() {
}
public boolean equals(Object o) {
if (o == null || !(o instanceof JavaVFrame)) {
return false;
}
JavaVFrame other = (JavaVFrame) o;
// Check static part
if (!getMethod().equals(other.getMethod())) {
return false;
}
if (getBCI() != other.getBCI()) {
return false;
}
// dynamic part - we just compare the frame pointer
if (! getFrame().equals(other.getFrame())) {
return false;
}
return true;
}
public int hashCode() {
return getMethod().hashCode() ^ getBCI() ^ getFrame().hashCode();
}
/** Structural compare */
public boolean structuralCompare(JavaVFrame other) {
// Check static part
if (!getMethod().equals(other.getMethod())) {
return false;
}
if (getBCI() != other.getBCI()) {
return false;
}
// Check locals
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++) {
// it might happen the compiler reports a conflict and
// the interpreter reports a bogus int.
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;
}
}
// Check expressions
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;
}
//--------------------------------------------------------------------------------
// Internals only below this point
//
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();
}
}
}