Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java @ 13705:ac5b0f31f7a2
Truffle API-change: FrameDescriptors are now stored in the RootNode in a final field instead of the CallTarget.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Fri, 17 Jan 2014 17:06:08 +0100 |
parents | 7588156f5cf9 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
2 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.runtime; | |
26 | |
27 import java.util.*; | |
28 import sun.jvm.hotspot.code.*; | |
29 import sun.jvm.hotspot.debugger.*; | |
30 import sun.jvm.hotspot.oops.*; | |
31 import sun.jvm.hotspot.utilities.*; | |
32 | |
33 /** FIXME: missing many accessors; all we have right now is the method | |
34 and BCI. NOTE that this has been modified from the VM's version to | |
35 handle NULL ScopeDescs for the debugging case. This simplifies | |
36 using code a great deal. */ | |
37 | |
38 public class CompiledVFrame extends JavaVFrame { | |
39 private ScopeDesc scope; | |
40 private boolean mayBeImprecise; | |
41 | |
42 public CompiledVFrame(Frame fr, RegisterMap regMap, JavaThread thread, ScopeDesc scope, boolean mayBeImprecise) { | |
43 super(fr, regMap, thread); | |
44 this.scope = scope; | |
45 this.mayBeImprecise = mayBeImprecise; | |
46 if (!VM.getVM().isDebugging()) { | |
47 Assert.that(scope != null, "scope must be present"); | |
48 } | |
49 } | |
50 | |
51 public boolean isTop() { | |
52 if (VM.getVM().isDebugging()) { | |
53 return (getScope() == null || getScope().isTop()); | |
54 } else { | |
55 return getScope().isTop(); | |
56 } | |
57 } | |
58 | |
59 public boolean isCompiledFrame() { | |
60 return true; | |
61 } | |
62 | |
63 public boolean isDeoptimized() { | |
64 return fr.isDeoptimized(); | |
65 } | |
66 | |
67 public boolean mayBeImpreciseDbg() { | |
68 return mayBeImprecise; | |
69 } | |
70 | |
71 /** Returns the active method */ | |
72 public NMethod getCode() { | |
73 return VM.getVM().getCodeCache().findNMethod(fr.getPC()); | |
74 } | |
75 | |
76 /** Returns the active method. Does not perform a guarantee | |
77 regarding unloaded methods -- more suitable for debugging | |
78 system. */ | |
79 public NMethod getCodeUnsafe() { | |
80 return VM.getVM().getCodeCache().findNMethodUnsafe(fr.getPC()); | |
81 } | |
82 | |
83 /** Returns the ScopeDesc */ | |
84 public ScopeDesc getScope() { | |
85 return scope; | |
86 } | |
87 | |
88 public Method getMethod() { | |
89 if (VM.getVM().isDebugging() && getScope() == null) { | |
90 return getCodeUnsafe().getMethod(); | |
91 } | |
92 return getScope().getMethod(); | |
93 } | |
94 | |
95 public StackValueCollection getLocals() { | |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
96 if (getScope() == null) |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
97 return new StackValueCollection(); |
0 | 98 List scvList = getScope().getLocals(); |
99 if (scvList == null) | |
100 return new StackValueCollection(); | |
101 | |
102 // scvList is the list of ScopeValues describing the JVM stack state. | |
103 // There is one scv_list entry for every JVM stack state in use. | |
104 int length = scvList.size(); | |
105 StackValueCollection result = new StackValueCollection(length); | |
106 for( int i = 0; i < length; i++ ) | |
107 result.add( createStackValue((ScopeValue) scvList.get(i)) ); | |
108 | |
109 return result; | |
110 } | |
111 | |
112 public StackValueCollection getExpressions() { | |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
113 if (getScope() == null) |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
114 return new StackValueCollection(); |
0 | 115 List scvList = getScope().getExpressions(); |
116 if (scvList == null) | |
117 return new StackValueCollection(); | |
118 | |
119 // scvList is the list of ScopeValues describing the JVM stack state. | |
120 // There is one scv_list entry for every JVM stack state in use. | |
121 int length = scvList.size(); | |
122 StackValueCollection result = new StackValueCollection(length); | |
123 for( int i = 0; i < length; i++ ) | |
124 result.add( createStackValue((ScopeValue) scvList.get(i)) ); | |
125 | |
126 return result; | |
127 } | |
128 | |
129 /** Returns List<MonitorInfo> */ | |
130 public List getMonitors() { | |
131 List monitors = getScope().getMonitors(); | |
132 if (monitors == null) { | |
133 return new ArrayList(); | |
134 } | |
135 List result = new ArrayList(monitors.size()); | |
136 for (int i = 0; i < monitors.size(); i++) { | |
137 MonitorValue mv = (MonitorValue) monitors.get(i); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
138 ScopeValue ov = mv.owner(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
139 StackValue ownerSV = createStackValue(ov); // it is an oop |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
140 if (ov.isObject()) { // The owner object was scalar replaced |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
141 Assert.that(mv.eliminated() && ownerSV.objIsScalarReplaced(), "monitor should be eliminated for scalar replaced object"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
142 // Put klass for scalar replaced object. |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
143 ScopeValue kv = ((ObjectValue)ov).getKlass(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
144 Assert.that(kv.isConstantOop(), "klass should be oop constant for scalar replaced object"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
145 OopHandle k = ((ConstantOopReadValue)kv).getValue(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
146 result.add(new MonitorInfo(k, resolveMonitorLock(mv.basicLock()), mv.eliminated(), true)); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
147 } else { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
148 result.add(new MonitorInfo(ownerSV.getObject(), resolveMonitorLock(mv.basicLock()), mv.eliminated(), false)); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
149 } |
0 | 150 } |
151 return result; | |
152 } | |
153 | |
154 public int getBCI() { | |
155 int raw = getRawBCI(); | |
156 return ((raw == DebugInformationRecorder.SYNCHRONIZATION_ENTRY_BCI) ? 0 : raw); | |
157 } | |
158 | |
159 /** Returns SynchronizationEntryBCI or bci() (used for synchronization) */ | |
160 public int getRawBCI() { | |
161 if (VM.getVM().isDebugging() && getScope() == null) { | |
162 return 0; // No debugging information! | |
163 } | |
164 return getScope().getBCI(); | |
165 } | |
166 | |
167 /** Returns the sender vframe */ | |
168 public VFrame sender() { | |
169 if (Assert.ASSERTS_ENABLED) { | |
170 Assert.that(isTop(), "just checking"); | |
171 } | |
172 return sender(false); | |
173 } | |
174 | |
175 public VFrame sender(boolean mayBeImprecise) { | |
176 if (!VM.getVM().isDebugging()) { | |
177 if (Assert.ASSERTS_ENABLED) { | |
178 Assert.that(scope != null, "When new stub generator is in place, then scope can never be NULL"); | |
179 } | |
180 } | |
181 Frame f = (Frame) getFrame().clone(); | |
182 return (isTop() | |
183 ? super.sender(false) | |
184 : new CompiledVFrame(f, getRegisterMap(), getThread(), getScope().sender(), mayBeImprecise)); | |
185 } | |
186 | |
187 private StackValue createStackValue(ScopeValue sv) { | |
188 // FIXME: this code appears to be out-of-date with respect to the VM especially in 64-bit mode | |
189 if (sv.isLocation()) { | |
190 // Stack or register value | |
191 Location loc = ((LocationValue) sv).getLocation(); | |
192 | |
193 if (loc.isIllegal()) return new StackValue(); | |
194 | |
195 // First find address of value | |
196 Address valueAddr = loc.isRegister() | |
197 // Value was in a callee-save register | |
198 ? getRegisterMap().getLocation(new VMReg(loc.getRegisterNumber())) | |
199 // Else value was directly saved on the stack. The frame's original stack pointer, | |
200 // before any extension by its callee (due to Compiler1 linkage on SPARC), must be used. | |
201 : ((Address)fr.getUnextendedSP()).addOffsetTo(loc.getStackOffset()); | |
202 | |
203 // Then package it right depending on type | |
204 if (loc.holdsFloat()) { // Holds a float in a double register? | |
205 // The callee has no clue whether the register holds a float, | |
206 // double or is unused. He always saves a double. Here we know | |
207 // a double was saved, but we only want a float back. Narrow the | |
208 // saved double to the float that the JVM wants. | |
209 if (Assert.ASSERTS_ENABLED) { | |
210 Assert.that( loc.isRegister(), "floats always saved to stack in 1 word" ); | |
211 } | |
212 float value = (float) valueAddr.getJDoubleAt(0); | |
213 return new StackValue(Float.floatToIntBits(value) & 0xFFFFFFFF); // 64-bit high half is stack junk | |
214 } else if (loc.holdsInt()) { // Holds an int in a long register? | |
215 // The callee has no clue whether the register holds an int, | |
216 // long or is unused. He always saves a long. Here we know | |
217 // a long was saved, but we only want an int back. Narrow the | |
218 // saved long to the int that the JVM wants. | |
219 if (Assert.ASSERTS_ENABLED) { | |
220 Assert.that( loc.isRegister(), "ints always saved to stack in 1 word" ); | |
221 } | |
222 return new StackValue(valueAddr.getJLongAt(0) & 0xFFFFFFFF); | |
331 | 223 } else if (loc.holdsNarrowOop()) { // Holds an narrow oop? |
224 if (loc.isRegister() && VM.getVM().isBigEndian()) { | |
225 // The callee has no clue whether the register holds an narrow oop, | |
226 // long or is unused. He always saves a long. Here we know | |
227 // a long was saved, but we only want an narrow oop back. Narrow the | |
228 // saved long to the narrow oop that the JVM wants. | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
229 return new StackValue(valueAddr.getCompOopHandleAt(VM.getVM().getIntSize()), 0); |
331 | 230 } else { |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
231 return new StackValue(valueAddr.getCompOopHandleAt(0), 0); |
331 | 232 } |
0 | 233 } else if( loc.holdsOop() ) { // Holds an oop? |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
234 return new StackValue(valueAddr.getOopHandleAt(0), 0); |
0 | 235 } else if( loc.holdsDouble() ) { |
236 // Double value in a single stack slot | |
237 return new StackValue(valueAddr.getJIntAt(0) & 0xFFFFFFFF); | |
238 } else if(loc.holdsAddr()) { | |
239 if (Assert.ASSERTS_ENABLED) { | |
240 Assert.that(!VM.getVM().isServerCompiler(), "No address type for locations with C2 (jsr-s are inlined)"); | |
241 } | |
242 // FIXME: not yet implemented (no access to safepoint state yet) | |
243 return new StackValue(0); | |
244 // intptr_t return_addr_tmp = *(intptr_t *)value_addr; | |
245 // int bci = -1; | |
246 // // Get the bci of the jsr that generated this returnAddress value. | |
247 // // If the destination of a jsr is a block that ends with a return or throw, then | |
248 // // the GraphBuilder converts the jsr into a direct goto. This has the side effect that | |
249 // // the return address for the jsr gets emitted as a bci instead of as a real pc | |
250 // if (code()->contains((address)return_addr_tmp)) { | |
251 // ScopeDesc* scope = code()->scope_desc_at((address)(return_addr_tmp - jsr_call_offset), false); | |
252 // bci = scope->bci(); | |
253 // } else { | |
254 // bci = (int)return_addr_tmp; | |
255 // } | |
256 // // no need to lock method as this happens at Safepoint | |
257 // assert (SafepointSynchronize::is_at_safepoint(), "must be at safepoint, otherwise lock method()"); | |
258 // // make sure bci points to jsr | |
259 // Bytecode* bytecode = Bytecode_at(method()->bcp_from(bci)); | |
260 // Bytecodes::Code bc = bytecode->code(); | |
261 // assert (bc == Bytecodes::_jsr || bc == Bytecodes::_jsr_w, "must be jsr"); | |
262 // | |
263 // // the real returnAddress is the bytecode following the jsr | |
264 // return new StackValue((intptr_t)(bci + Bytecodes::length_for(bc))); | |
265 } else if (VM.getVM().isLP64() && loc.holdsLong()) { | |
266 if ( loc.isRegister() ) { | |
267 // Long value in two registers, high half in the first, low in the second | |
268 return new StackValue(((valueAddr.getJLongAt(0) & 0xFFFFFFFF) << 32) | | |
269 ((valueAddr.getJLongAt(8) & 0xFFFFFFFF))); | |
270 } else { | |
271 // Long value in a single stack slot | |
272 return new StackValue(valueAddr.getJLongAt(0)); | |
273 } | |
274 } else if( loc.isRegister() ) { | |
275 // At the moment, all non-oop values in registers are 4 bytes, | |
276 // including double and long halves (see Compile::FillLocArray() in | |
277 // opto/output.cpp). Haul them out as such and return a StackValue | |
278 // containing an image of the value as it appears in a stack slot. | |
279 // If this is a double or long half, the interpreter _must_ deal | |
280 // with doubles and longs as entities split across two stack slots. | |
281 // To change this so doubles and/or longs can live in one stack slot, | |
282 // a StackValue will have to understand that it can contain an | |
283 // undivided double or long, implying that a Location (and the debug | |
284 // info mechanism) and FillLocArray() will also have to understand it. | |
285 return new StackValue(valueAddr.getJIntAt(0) & 0xFFFFFFFF); | |
286 } else { | |
287 return new StackValue(valueAddr.getJIntAt(0) & 0xFFFFFFFF); | |
288 } | |
289 } else if (sv.isConstantInt()) { | |
290 // Constant int: treat same as register int. | |
291 return new StackValue(((ConstantIntValue) sv).getValue() & 0xFFFFFFFF); | |
292 } else if (sv.isConstantOop()) { | |
293 // constant oop | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
294 return new StackValue(((ConstantOopReadValue) sv).getValue(), 0); |
0 | 295 } else if (sv.isConstantDouble()) { |
296 // Constant double in a single stack slot | |
297 double d = ((ConstantDoubleValue) sv).getValue(); | |
298 return new StackValue(Double.doubleToLongBits(d) & 0xFFFFFFFF); | |
299 } else if (VM.getVM().isLP64() && sv.isConstantLong()) { | |
300 // Constant long in a single stack slot | |
301 return new StackValue(((ConstantLongValue) sv).getValue() & 0xFFFFFFFF); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
302 } else if (sv.isObject()) { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
303 // Scalar replaced object in compiled frame |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
337
diff
changeset
|
304 return new StackValue(((ObjectValue)sv).getValue(), 1); |
0 | 305 } |
306 | |
307 // Unknown ScopeValue type | |
308 Assert.that(false, "Should not reach here"); | |
309 return new StackValue(0); // dummy | |
310 } | |
311 | |
312 private BasicLock resolveMonitorLock(Location location) { | |
313 if (Assert.ASSERTS_ENABLED) { | |
314 Assert.that(location.isStack(), "for now we only look at the stack"); | |
315 } | |
316 int byteOffset = location.getStackOffset(); | |
317 // (stack picture) | |
318 // high: [ ] byte_offset + wordSize | |
319 // low [ ] byte_offset | |
320 // | |
321 // sp-> [ ] 0 | |
322 // the byte_offset is the distance from the stack pointer to the lowest address | |
323 // The frame's original stack pointer, before any extension by its callee | |
324 // (due to Compiler1 linkage on SPARC), must be used. | |
325 return new BasicLock(getFrame().getUnextendedSP().addOffsetTo(byteOffset)); | |
326 } | |
327 } |