0
|
1 /*
|
|
2 * Copyright 2000-2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 package sun.jvm.hotspot.runtime;
|
|
26
|
|
27 import java.io.*;
|
|
28 import sun.jvm.hotspot.code.*;
|
|
29 import sun.jvm.hotspot.utilities.*;
|
|
30
|
|
31 public class VFrame {
|
|
32 protected Frame fr;
|
|
33 protected RegisterMap regMap;
|
|
34 protected JavaThread thread;
|
|
35
|
|
36 protected VFrame(Frame f, RegisterMap regMap, JavaThread thread) {
|
|
37 this.regMap = (RegisterMap) regMap.clone();
|
|
38
|
|
39 if (f != null) {
|
|
40 // the frame is null if we create a deoptimizedVFrame from a vframeArray
|
|
41 fr = (Frame) f.clone();
|
|
42 }
|
|
43
|
|
44 this.thread = thread;
|
|
45 }
|
|
46
|
|
47 /** Factory method for creating vframes. The "unsafe" flag turns off
|
|
48 an assertion which the runtime system uses to ensure integrity,
|
|
49 but which must not be applied in the debugging situation. The
|
|
50 "mayBeImprecise" flag should be set to true for the case of the
|
|
51 top frame in the debugging system (obtained via
|
|
52 JavaThread.getCurrentFrameGuess()). */
|
|
53 public static VFrame newVFrame(Frame f, RegisterMap regMap, JavaThread thread, boolean unsafe, boolean mayBeImprecise) {
|
|
54 if (f.isInterpretedFrame()) {
|
|
55 return new InterpretedVFrame(f, regMap, thread);
|
|
56 }
|
|
57
|
|
58 if (!VM.getVM().isCore()) {
|
|
59 CodeBlob cb;
|
|
60 if (unsafe) {
|
|
61 cb = VM.getVM().getCodeCache().findBlobUnsafe(f.getPC());
|
|
62 } else {
|
|
63 cb = VM.getVM().getCodeCache().findBlob(f.getPC());
|
|
64 }
|
|
65
|
|
66 if (cb != null) {
|
|
67 if (cb.isNMethod()) {
|
|
68 NMethod nm = (NMethod) cb;
|
|
69 // Compiled method (native stub or Java code)
|
|
70 ScopeDesc scope = null;
|
|
71 // FIXME: should revisit the check of isDebugging(); should not be necessary
|
|
72 if (mayBeImprecise || VM.getVM().isDebugging()) {
|
|
73 scope = nm.getScopeDescNearDbg(f.getPC());
|
|
74 } else {
|
|
75 scope = nm.getScopeDescAt(f.getPC());
|
|
76 }
|
|
77 return new CompiledVFrame(f, regMap, thread, scope, mayBeImprecise);
|
|
78 }
|
|
79
|
|
80 if (f.isGlueFrame()) {
|
|
81 // This is a conversion frame. Skip this frame and try again.
|
|
82 RegisterMap tempMap = regMap.copy();
|
|
83 Frame s = f.sender(tempMap);
|
|
84 return newVFrame(s, tempMap, thread, unsafe, false);
|
|
85 }
|
|
86 }
|
|
87 }
|
|
88
|
|
89 // External frame
|
|
90 return new ExternalVFrame(f, regMap, thread, mayBeImprecise);
|
|
91 }
|
|
92
|
|
93 /** Factory method for creating vframes. This is equivalent to
|
|
94 calling the above version with the "unsafe" and "imprecise"
|
|
95 flags set to false. */
|
|
96 public static VFrame newVFrame(Frame f, RegisterMap regMap, JavaThread thread) {
|
|
97 return newVFrame(f, regMap, thread, false, false);
|
|
98 }
|
|
99
|
|
100 /** Accessors */
|
|
101 public Frame getFrame() { return fr; }
|
|
102 public RegisterMap getRegisterMap() { return regMap; }
|
|
103 public JavaThread getThread() { return thread; }
|
|
104
|
|
105 /** Returns the sender vframe */
|
|
106 public VFrame sender() {
|
|
107 if (Assert.ASSERTS_ENABLED) {
|
|
108 Assert.that(isTop(), "just checking");
|
|
109 }
|
|
110 return sender(false);
|
|
111 }
|
|
112
|
|
113 /** Returns the sender vframe; takes argument for debugging situation */
|
|
114 public VFrame sender(boolean mayBeImprecise) {
|
|
115 RegisterMap tempMap = (RegisterMap) getRegisterMap().clone();
|
|
116 if (fr.isFirstFrame()) {
|
|
117 return null;
|
|
118 }
|
|
119 Frame s = fr.realSender(tempMap);
|
|
120 // ia64 in 1.4.1 only has java frames and no entryFrame
|
|
121 // so "s" can be null here for the first frame.
|
|
122 if (s == null) {
|
|
123 Assert.that(VM.getVM().getCPU().equals("ia64"), "Only ia64 should have null here");
|
|
124 return null;
|
|
125 }
|
|
126 if (s.isFirstFrame()) {
|
|
127 return null;
|
|
128 }
|
|
129 return VFrame.newVFrame(s, tempMap, getThread(), VM.getVM().isDebugging(), mayBeImprecise);
|
|
130 }
|
|
131
|
|
132 /** Returns the next javaVFrame on the stack (skipping all other
|
|
133 kinds of frames). In the debugging situation, allows the
|
|
134 "imprecise" flag to propagate up the stack. We must not assert
|
|
135 that a ScopeDesc exists for the topmost compiled frame on the
|
|
136 stack. */
|
|
137 public JavaVFrame javaSender() {
|
|
138 boolean imprecise = false;
|
|
139
|
|
140 // Hack for debugging
|
|
141 if (VM.getVM().isDebugging()) {
|
|
142 if (!isJavaFrame()) {
|
|
143 imprecise = mayBeImpreciseDbg();
|
|
144 }
|
|
145 }
|
|
146 VFrame f = sender(imprecise);
|
|
147 while (f != null) {
|
|
148 if (f.isJavaFrame()) {
|
|
149 return (JavaVFrame) f;
|
|
150 }
|
|
151 f = f.sender(imprecise);
|
|
152 }
|
|
153 return null;
|
|
154 }
|
|
155
|
|
156 /** Answers if the this is the top vframe in the frame, i.e., if the
|
|
157 sender vframe is in the caller frame */
|
|
158 public boolean isTop() {
|
|
159 return true;
|
|
160 }
|
|
161
|
|
162 /** Returns top vframe within same frame (see isTop()) */
|
|
163 public VFrame top() {
|
|
164 VFrame vf = this;
|
|
165 while (!vf.isTop()) {
|
|
166 vf = vf.sender();
|
|
167 }
|
|
168 return vf;
|
|
169 }
|
|
170
|
|
171 /** Type testing operations */
|
|
172 public boolean isEntryFrame() { return false; }
|
|
173 public boolean isJavaFrame() { return false; }
|
|
174 public boolean isInterpretedFrame() { return false; }
|
|
175 public boolean isCompiledFrame() { return false; }
|
|
176 public boolean isDeoptimized() { return false; }
|
|
177
|
|
178 /** An indication of whether this VFrame is "precise" or a best
|
|
179 guess. This is used in the debugging system to handle the top
|
|
180 frame on the stack, which, since the system will in general not
|
|
181 be at a safepoint, has to make some guesses about exactly where
|
|
182 in the execution it is. Any debugger should indicate to the user
|
|
183 that the information for this frame may not be 100% correct.
|
|
184 FIXME: may need to move this up into VFrame instead of keeping
|
|
185 it in CompiledVFrame. */
|
|
186 public boolean mayBeImpreciseDbg() { return false; }
|
|
187
|
|
188 /** Printing operations */
|
|
189 public void print() {
|
|
190 printOn(System.out);
|
|
191 }
|
|
192
|
|
193 public void printOn(PrintStream tty) {
|
|
194 if (VM.getVM().wizardMode()) {
|
|
195 fr.printValueOn(tty);
|
|
196 }
|
|
197 }
|
|
198
|
|
199 public void printValue() {
|
|
200 printValueOn(System.out);
|
|
201 }
|
|
202
|
|
203 public void printValueOn(PrintStream tty) {
|
|
204 printOn(tty);
|
|
205 }
|
|
206 }
|