1/*
2 * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25package sun.jvm.hotspot.runtime;
26
27import java.io.*;
28import java.util.*;
29import sun.jvm.hotspot.oops.*;
30import sun.jvm.hotspot.utilities.*;
31
32public abstract class JavaVFrame extends VFrame {
33  /** JVM state */
34  public abstract Method getMethod();
35  public abstract int    getBCI();
36  public abstract StackValueCollection getLocals();
37  public abstract StackValueCollection getExpressions();
38  public abstract List   getMonitors();    // List<MonitorInfo>
39
40  /** Test operation */
41  public boolean isJavaFrame() { return true; }
42
43  /** Package-internal constructor */
44  JavaVFrame(Frame fr, RegisterMap regMap, JavaThread thread) {
45    super(fr, regMap, thread);
46  }
47
48  /** Get monitor (if any) that this JavaVFrame is trying to enter */
49  // FIXME: not yet implemented
50  //  public Address getPendingMonitor(int frameCount);
51
52  /** Printing used during stack dumps */
53  // FIXME: not yet implemented
54  //  void print_lock_info(int frame_count);
55
56  /** Printing operations */
57
58  //
59  // FIXME: implement visitor pattern for traversing vframe contents?
60  //
61
62  public void print() {
63    printOn(System.out);
64  }
65
66  public void printOn(PrintStream tty) {
67    super.printOn(tty);
68
69    tty.print("\t");
70    getMethod().printValueOn(tty);
71    tty.println();
72    tty.println("\tbci:\t" + getBCI());
73
74    printStackValuesOn(tty, "locals",      getLocals());
75    printStackValuesOn(tty, "expressions", getExpressions());
76
77    // List<MonitorInfo>
78    // FIXME: not yet implemented
79    //    List list = getMonitors();
80    //    if (list.isEmpty()) {
81    //      return;
82    //    }
83    //    for (int index = 0; index < list.size(); index++) {
84    //      MonitorInfo monitor = (MonitorInfo) list.get(index);
85    //      tty.print("\t  obj\t");
86    //      monitor.getOwner().printValueOn(tty);
87    //      tty.println();
88    //      tty.print("\t  ");
89    //      monitor.lock().printOn(tty);
90    //      tty.println();
91    //    }
92  }
93
94  public void printActivation(int index) {
95    printActivationOn(System.out, index);
96  }
97
98  public void printActivationOn(PrintStream tty, int index) {
99    // frame number and method
100    tty.print(index + " - ");
101    printValueOn(tty);
102    tty.println();
103
104    if (VM.getVM().wizardMode()) {
105      printOn(tty);
106      tty.println();
107    }
108  }
109
110  /** Verification operations */
111  public void verify() {
112  }
113
114  public boolean equals(Object o) {
115      if (o == null || !(o instanceof JavaVFrame)) {
116          return false;
117      }
118
119      JavaVFrame other = (JavaVFrame) o;
120
121      // Check static part
122      if (!getMethod().equals(other.getMethod())) {
123          return false;
124      }
125
126      if (getBCI() != other.getBCI()) {
127          return false;
128      }
129
130      // dynamic part - we just compare the frame pointer
131      if (! getFrame().equals(other.getFrame())) {
132          return false;
133      }
134      return true;
135  }
136
137  public int hashCode() {
138      return getMethod().hashCode() ^ getBCI() ^ getFrame().hashCode();
139  }
140
141  /** Structural compare */
142  public boolean structuralCompare(JavaVFrame other) {
143    // Check static part
144    if (!getMethod().equals(other.getMethod())) {
145      return false;
146    }
147
148    if (getBCI() != other.getBCI()) {
149      return false;
150    }
151
152    // Check locals
153    StackValueCollection locs      = getLocals();
154    StackValueCollection otherLocs = other.getLocals();
155    if (Assert.ASSERTS_ENABLED) {
156      Assert.that(locs.size() == otherLocs.size(), "sanity check");
157    }
158    for (int i = 0; i < locs.size(); i++) {
159      // it might happen the compiler reports a conflict and
160      // the interpreter reports a bogus int.
161      if (      isCompiledFrame() && (locs.get(i)).getType()      == BasicType.getTConflict()) continue;
162      if (other.isCompiledFrame() && (otherLocs.get(i)).getType() == BasicType.getTConflict()) continue;
163
164      if (!locs.get(i).equals(otherLocs.get(i))) {
165        return false;
166      }
167    }
168
169    // Check expressions
170    StackValueCollection exprs      = getExpressions();
171    StackValueCollection otherExprs = other.getExpressions();
172    if (Assert.ASSERTS_ENABLED) {
173      Assert.that(exprs.size() == otherExprs.size(), "sanity check");
174    }
175    for (int i = 0; i < exprs.size(); i++) {
176      if (!exprs.get(i).equals(otherExprs.get(i))) {
177        return false;
178      }
179    }
180
181    return true;
182  }
183
184  //--------------------------------------------------------------------------------
185  // Internals only below this point
186  //
187
188  private void printStackValuesOn(PrintStream tty, String title, StackValueCollection values) {
189    if (values.isEmpty()) {
190      return;
191    }
192    tty.println("\t" + title + ":");
193    for (int index = 0; index < values.size(); index++) {
194      tty.print("\t" + index + "\t");
195      values.get(index).printOn(tty);
196      tty.println();
197    }
198  }
199}
200