Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java @ 18665:96861e3f8cc5
made CFGPrinterObserver reset (upon close) properly
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 11 Dec 2014 22:14:30 +0100 |
parents | da91efe96a93 |
children | c5f6a7397eb1 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2 * Copyright (c) 2000, 2012, 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:
196
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
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:
196
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.runtime; | |
26 | |
27 import java.io.*; | |
28 import java.util.*; | |
29 import sun.jvm.hotspot.*; | |
30 import sun.jvm.hotspot.code.*; | |
31 import sun.jvm.hotspot.compiler.*; | |
32 import sun.jvm.hotspot.c1.*; | |
33 import sun.jvm.hotspot.debugger.*; | |
34 import sun.jvm.hotspot.interpreter.*; | |
35 import sun.jvm.hotspot.oops.*; | |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
36 import sun.jvm.hotspot.runtime.sparc.SPARCFrame; |
0 | 37 import sun.jvm.hotspot.types.*; |
38 import sun.jvm.hotspot.utilities.*; | |
39 | |
40 /** <P> A frame represents a physical stack frame (an activation). | |
41 Frames can be C or Java frames, and the Java frames can be | |
42 interpreted or compiled. In contrast, vframes represent | |
43 source-level activations, so that one physical frame can | |
44 correspond to multiple source level frames because of inlining. | |
45 </P> | |
46 | |
47 <P> NOTE that this is not a VMObject and does not wrap an Address | |
48 -- this is an actual port of the VM's Frame code to Java. </P> | |
49 | |
50 <P> NOTE also that this is incomplete -- just trying to get | |
51 reading of interpreted frames working for now, so all non-core and | |
52 setter methods are removed for now. (FIXME) </P> */ | |
53 | |
54 public abstract class Frame implements Cloneable { | |
55 /** A raw stack pointer. The accessor getSP() will return a real (usable) | |
56 stack pointer (e.g. from Thread::last_Java_sp) */ | |
57 protected Address raw_sp; | |
58 | |
59 /** Program counter (the next instruction after the call) */ | |
60 protected Address pc; | |
61 protected boolean deoptimized; | |
62 | |
63 public Frame() { | |
64 deoptimized = false; | |
65 } | |
66 | |
67 static { | |
68 VM.registerVMInitializedObserver(new Observer() { | |
69 public void update(Observable o, Object data) { | |
70 initialize(VM.getVM().getTypeDataBase()); | |
71 } | |
72 }); | |
73 } | |
74 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
75 /** Size of ConstMethod for computing BCI from BCP (FIXME: hack) */ |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
76 private static long ConstMethodSize; |
0 | 77 |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
78 private static int pcReturnOffset; |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
79 |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
80 public static int pcReturnOffset() { |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
81 return pcReturnOffset; |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
82 } |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
83 |
0 | 84 private static synchronized void initialize(TypeDataBase db) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
85 Type ConstMethodType = db.lookupType("ConstMethod"); |
0 | 86 // FIXME: not sure whether alignment here is correct or how to |
87 // force it (round up to address size?) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
88 ConstMethodSize = ConstMethodType.getSize(); |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
89 |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
90 pcReturnOffset = db.lookupIntConstant("frame::pc_return_offset").intValue(); |
0 | 91 } |
92 | |
93 protected int bcpToBci(Address bcp, ConstMethod cm) { | |
94 // bcp will be null for interpreter native methods | |
95 // in addition depending on where we catch the system the value can | |
96 // be a bcp or a bci. | |
97 if (bcp == null) return 0; | |
98 long bci = bcp.minus(null); | |
99 if (bci >= 0 && bci < cm.getCodeSize()) return (int) bci; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
100 return (int) (bcp.minus(cm.getAddress()) - ConstMethodSize); |
0 | 101 } |
102 | |
103 protected int bcpToBci(Address bcp, Method m) { | |
104 return bcpToBci(bcp, m.getConstMethod()); | |
105 } | |
106 | |
107 public abstract Object clone(); | |
108 | |
109 // Accessors | |
110 | |
111 /** pc: Returns the pc at which this frame will continue normally. | |
112 It must point at the beginning of the next instruction to | |
113 execute. */ | |
114 public Address getPC() { return pc; } | |
115 public void setPC(Address newpc) { pc = newpc; } | |
116 public boolean isDeoptimized() { return deoptimized; } | |
117 | |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
118 public CodeBlob cb() { |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
119 return VM.getVM().getCodeCache().findBlob(getPC()); |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
120 } |
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
121 |
0 | 122 public abstract Address getSP(); |
123 public abstract Address getID(); | |
124 public abstract Address getFP(); | |
125 | |
126 /** testers -- platform dependent */ | |
127 public abstract boolean equals(Object arg); | |
128 | |
129 /** type testers */ | |
130 public boolean isInterpretedFrame() { return VM.getVM().getInterpreter().contains(getPC()); } | |
131 public boolean isJavaFrame() { | |
132 if (isInterpretedFrame()) return true; | |
133 if (!VM.getVM().isCore()) { | |
134 if (isCompiledFrame()) return true; | |
135 } | |
136 return false; | |
137 } | |
138 | |
139 /** Java frame called from C? */ | |
140 public boolean isEntryFrame() { return VM.getVM().getStubRoutines().returnsToCallStub(getPC()); } | |
141 public boolean isNativeFrame() { | |
142 if (!VM.getVM().isCore()) { | |
143 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); | |
144 return (cb != null && cb.isNativeMethod()); | |
145 } else { | |
146 return false; | |
147 } | |
148 } | |
149 | |
150 public boolean isCompiledFrame() { | |
151 if (Assert.ASSERTS_ENABLED) { | |
152 Assert.that(!VM.getVM().isCore(), "noncore builds only"); | |
153 } | |
154 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); | |
155 return (cb != null && cb.isJavaMethod()); | |
156 } | |
157 | |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
1552
diff
changeset
|
158 public boolean isRuntimeFrame() { |
0 | 159 if (Assert.ASSERTS_ENABLED) { |
160 Assert.that(!VM.getVM().isCore(), "noncore builds only"); | |
161 } | |
162 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); | |
163 if (cb == null) { | |
164 return false; | |
165 } | |
166 if (cb.isRuntimeStub()) return true; | |
167 else return false; | |
168 } | |
169 | |
170 /** oldest frame? (has no sender) FIXME: this is modified from the | |
171 C++ code to handle the debugging situation where we try to | |
172 traverse the stack for, for example, the signal thread, and | |
173 don't find any valid Java frames. Would really like to put the | |
174 second half of the conditional in some sort of debugging-only if | |
175 statement. */ | |
176 // *** FIXME: THE CALL TO isJavaFrame() IS WAY TOO EXPENSIVE!!!!! *** | |
177 public boolean isFirstFrame() { return ((isEntryFrame() && entryFrameIsFirst()) || | |
178 (!isJavaFrame() && !hasSenderPD())); } | |
179 /** same for Java frame */ | |
180 public boolean isFirstJavaFrame() { throw new RuntimeException("not yet implemented"); } | |
181 | |
182 /** This is an addition for debugging purposes on platforms which | |
183 have the notion of signals. */ | |
184 public abstract boolean isSignalHandlerFrameDbg(); | |
185 | |
186 /** If this is a signal handler frame (again, on a platform with a | |
187 notion of signals), get the signal number. */ | |
188 public abstract int getSignalNumberDbg(); | |
189 | |
190 /** If this is a signal handler frame (again, on a platform with a | |
191 notion of signals), get the name of the signal. */ | |
192 public abstract String getSignalNameDbg(); | |
193 | |
194 /** performs sanity checks on interpreted frames. */ | |
195 public abstract boolean isInterpretedFrameValid(); | |
196 | |
197 /** tells whether this frame is marked for deoptimization */ | |
198 public boolean shouldBeDeoptimized() { throw new RuntimeException("not yet implemented"); } | |
199 | |
200 /** tells whether this frame can be deoptimized */ | |
201 public boolean canBeDeoptimized() { throw new RuntimeException("not yet implemented"); } | |
202 | |
203 /** returns the sending frame */ | |
204 public abstract Frame sender(RegisterMap map, CodeBlob nm); | |
205 | |
206 /** equivalent to sender(map, null) */ | |
207 public Frame sender(RegisterMap map) { return sender(map, null); } | |
208 | |
209 /** returns the sender, but skips conversion frames */ | |
210 public Frame realSender(RegisterMap map) { | |
211 if (!VM.getVM().isCore()) { | |
212 Frame result = sender(map); | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3908
diff
changeset
|
213 while (result.isRuntimeFrame()) { |
0 | 214 result = result.sender(map); |
215 } | |
216 return result; | |
217 } else { | |
218 return sender(map); | |
219 } | |
220 } | |
221 | |
222 /** Platform-dependent query indicating whether this frame has a | |
223 sender. Should return true if it is possible to call sender() at | |
224 all on this frame. (This is currently only needed for the | |
225 debugging system, if a stack trace is attempted for a Java | |
226 thread which has no Java frames, i.e., the signal thread; we | |
227 have to know to stop traversal at the bottom frame.) */ | |
228 protected abstract boolean hasSenderPD(); | |
229 | |
230 //-------------------------------------------------------------------------------- | |
231 // All frames: | |
232 // A low-level interface for vframes: | |
233 | |
234 /** Returns the address of the requested "slot" on the stack. Slots | |
235 are as wide as addresses, so are 32 bits wide on a 32-bit | |
236 machine and 64 bits wide on a 64-bit machine. */ | |
237 public Address addressOfStackSlot(int slot) { return getFP().addOffsetTo(slot * VM.getVM().getAddressSize()); } | |
238 | |
239 /** Fetches the OopHandle at the requested slot */ | |
240 public OopHandle getOopHandleAt(int slot) { return addressOfStackSlot(slot).getOopHandleAt(0); } | |
241 /** Fetches the OopHandle at the slot, adjusted for compiler frames */ | |
242 // FIXME: looks like this is only used for compiled frames | |
243 // public OopHandle getOopHandleAtAdjusted(MethodOop method, int slot) { return addressOfStackSlot(slot).getOopHandleAt(0); } | |
244 // FIXME: Not yet implementable | |
245 // public void setOopHandleAt(int slot, OopHandle value) { addressOfStackSlot(slot).setOopHandleAt(0, value); } | |
246 | |
247 /** Fetches the (Java) int at the requested slot */ | |
248 public int getIntAt(int slot) { return addressOfStackSlot(slot).getJIntAt(0); } | |
249 // FIXME: Not yet implementable | |
250 // public void setIntAt(int slot, int value) { addressOfStackSlot(slot).setJIntAt(0, value); } | |
251 | |
252 /** returns the frame size in stack slots */ | |
253 public abstract long frameSize(); | |
254 | |
255 /** Link (i.e., the pointer to the previous frame) */ | |
256 public abstract Address getLink(); | |
257 // public abstract void setLink(Address addr); | |
258 | |
259 /** Return address */ | |
260 public abstract Address getSenderPC(); | |
261 // FIXME: currently unimplementable | |
262 // public abstract void setSenderPC(Address addr); | |
263 | |
264 /** The frame's original SP, before any extension by an interpreted | |
265 callee; used for packing debug info into vframeArray objects and | |
266 vframeArray lookup. */ | |
267 public abstract Address getUnextendedSP(); | |
268 | |
269 /** Returns the stack pointer of the calling frame */ | |
270 public abstract Address getSenderSP(); | |
271 | |
272 //-------------------------------------------------------------------------------- | |
273 // Interpreter frames: | |
274 // | |
275 | |
276 public abstract Address addressOfInterpreterFrameLocals(); | |
277 | |
278 public Address addressOfInterpreterFrameLocal(int slot) { | |
279 return addressOfInterpreterFrameLocals().getAddressAt(0).addOffsetTo(-slot * VM.getVM().getAddressSize()); | |
280 } | |
281 | |
282 // FIXME: not yet implementable | |
283 // void interpreter_frame_set_locals(intptr_t* locs); | |
284 | |
285 // NOTE that the accessor "addressOfInterpreterFrameBCX" has | |
286 // necessarily been eliminated. The byte code pointer is inherently | |
287 // an interior pointer to a Method (the bytecodes follow the | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
288 // Method data structure) and therefore acquisition of it in |
0 | 289 // this system can not be allowed. All accesses to interpreter frame |
290 // byte codes are via the byte code index (BCI). | |
291 | |
292 /** Byte code index. In the underlying frame, what is actually | |
293 stored is a byte code pointer (BCP), which is converted to a BCI | |
294 and back by the GC when methods are moved. In this system, | |
295 interior pointers are not allowed, so we must make the access to | |
296 the interpreter frame's BCI atomic with respect to GC. This may | |
297 mean implementation with an underlying call through native code | |
298 into the VM or a magic sequence in the compiler. (FIXME) */ | |
299 public abstract int getInterpreterFrameBCI(); | |
300 // FIXME: not yet implementable | |
301 // public abstract void setInterpreterFrameBCI(int bci); | |
302 | |
303 // FIXME: elided for now | |
304 // public abstract Address addressOfInterpreterCalleeReceiver(Symbol signature); | |
305 | |
306 /** Find receiver for an invoke when arguments are just pushed on | |
307 stack (i.e., callee stack-frame is not setup) */ | |
308 // FIXME: elided for now | |
309 // public OopHandle getInterpreterCalleeReceiver(SymbolOop signature) { return addressOfInterpreterCalleeReceiver(signature).getOopHandleAt(0); } | |
310 | |
311 //-------------------------------------------------------------------------------- | |
312 // Expression stack (may go up or down, direction == 1 or -1) | |
313 // | |
314 | |
315 public abstract Address addressOfInterpreterFrameExpressionStack(); | |
316 public abstract int getInterpreterFrameExpressionStackDirection(); | |
317 public Address addressOfInterpreterFrameExpressionStackSlot(int slot) { | |
318 return addressOfInterpreterFrameExpressionStack().addOffsetTo(-slot * VM.getVM().getAddressSize()); | |
319 } | |
320 | |
321 /** Top of expression stack */ | |
322 public abstract Address addressOfInterpreterFrameTOS(); | |
323 | |
324 /** Expression stack from top down */ | |
325 public abstract Address addressOfInterpreterFrameTOSAt(int slot); | |
326 | |
327 /** FIXME: is this portable? */ | |
328 public int getInterpreterFrameExpressionStackSize() { | |
329 return (int) (1 + (getInterpreterFrameExpressionStackDirection() * | |
330 (addressOfInterpreterFrameTOS().minus(addressOfInterpreterFrameExpressionStack())))); | |
331 } | |
332 | |
333 public abstract Address getInterpreterFrameSenderSP(); | |
334 // FIXME: not yet implementable | |
335 // public abstract void setInterpreterFrameSenderSP(Address senderSP); | |
336 | |
337 //-------------------------------------------------------------------------------- | |
338 // BasicObjectLocks: | |
339 // | |
340 | |
341 public abstract BasicObjectLock interpreterFrameMonitorBegin(); | |
342 public abstract BasicObjectLock interpreterFrameMonitorEnd(); | |
343 /** NOTE: this returns a size in BYTES in this system! */ | |
344 public abstract int interpreterFrameMonitorSize(); | |
345 public BasicObjectLock nextMonitorInInterpreterFrame(BasicObjectLock cur) { | |
346 return new BasicObjectLock(cur.address().addOffsetTo(interpreterFrameMonitorSize())); | |
347 } | |
348 public BasicObjectLock previousMonitorInInterpreterFrame(BasicObjectLock cur) { | |
349 return new BasicObjectLock(cur.address().addOffsetTo(-1 * interpreterFrameMonitorSize())); | |
350 } | |
351 | |
352 // interpreter_frame_monitor_begin is higher in memory than interpreter_frame_monitor_end | |
353 // Interpreter_frame_monitor_begin points to one element beyond the oldest one, | |
354 // interpreter_frame_monitor_end points to the youngest one, or if there are none, | |
355 // it points to one beyond where the first element will be. | |
356 // interpreter_frame_monitor_size reports the allocation size of a monitor in the interpreter stack. | |
357 // this value is >= BasicObjectLock::size(), and may be rounded up | |
358 | |
359 // FIXME: avoiding implementing this for now if possible | |
360 // public void interpreter_frame_set_monitor_end(BasicObjectLock* value); | |
361 // public void interpreter_frame_verify_monitor(BasicObjectLock* value) const; | |
362 // | |
363 // Tells whether the current interpreter_frame frame pointer | |
364 // corresponds to the old compiled/deoptimized fp | |
365 // The receiver used to be a top level frame | |
366 // public boolean interpreter_frame_equals_unpacked_fp(intptr_t* fp); | |
367 | |
368 //-------------------------------------------------------------------------------- | |
369 // Method and constant pool cache: | |
370 // | |
371 | |
372 /** Current method */ | |
373 public abstract Address addressOfInterpreterFrameMethod(); | |
374 | |
375 /** Current method */ | |
376 public Method getInterpreterFrameMethod() { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
377 return (Method)Metadata.instantiateWrapperFor(addressOfInterpreterFrameMethod().getAddressAt(0)); |
0 | 378 } |
379 | |
380 /** Current method */ | |
381 // FIXME: not yet implementable | |
382 // public void setInterpreterFrameMethod(Method method); | |
383 | |
384 /** Constant pool cache */ | |
385 public abstract Address addressOfInterpreterFrameCPCache(); | |
386 /** Constant pool cache */ | |
387 public ConstantPoolCache getInterpreterFrameCPCache() { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
388 return (ConstantPoolCache) Metadata.instantiateWrapperFor(addressOfInterpreterFrameCPCache().getAddressAt(0)); |
0 | 389 } |
390 | |
391 //-------------------------------------------------------------------------------- | |
392 // Entry frames: | |
393 // | |
394 | |
395 public abstract JavaCallWrapper getEntryFrameCallWrapper(); | |
396 | |
397 // FIXME: add | |
398 // inline intptr_t* entry_frame_argument_at(int offset) const; | |
399 | |
400 | |
401 /** Tells whether there is another chunk of Delta stack above */ | |
402 public boolean entryFrameIsFirst() { return (getEntryFrameCallWrapper().getLastJavaSP() == null); } | |
403 | |
404 //-------------------------------------------------------------------------------- | |
405 // Safepoints: | |
406 // | |
407 | |
408 protected abstract Address addressOfSavedOopResult(); | |
409 protected abstract Address addressOfSavedReceiver(); | |
410 | |
411 public OopHandle getSavedOopResult() { | |
412 return addressOfSavedOopResult().getOopHandleAt(0); | |
413 } | |
414 | |
415 // FIXME: not yet implementable | |
416 // public void setSavedOopResult(OopHandle obj); | |
417 | |
418 public OopHandle getSavedReceiver() { | |
419 return addressOfSavedReceiver().getOopHandleAt(0); | |
420 } | |
421 | |
422 // FIXME: not yet implementable | |
423 // public void setSavedReceiver(OopHandle obj); | |
424 | |
425 //-------------------------------------------------------------------------------- | |
426 // Oop traversals: | |
427 // | |
428 | |
429 public void oopsInterpretedArgumentsDo(Symbol signature, boolean isStatic, AddressVisitor f) { | |
430 ArgumentOopFinder finder = new ArgumentOopFinder(signature, isStatic, this, f); | |
431 finder.oopsDo(); | |
432 } | |
433 | |
434 /** Conversion from an VMReg::Name to physical stack location */ | |
435 public Address oopMapRegToLocation(VMReg reg, RegisterMap regMap) { | |
436 VMReg stack0 = VM.getVM().getVMRegImplInfo().getStack0(); | |
437 if (reg.lessThan(stack0)) { | |
438 // If it is passed in a register, it got spilled in the stub frame. | |
439 return regMap.getLocation(reg); | |
440 } else { | |
441 long spOffset = VM.getVM().getAddressSize() * reg.minus(stack0); | |
442 return getUnextendedSP().addOffsetTo(spOffset); | |
443 } | |
444 } | |
445 | |
446 public void oopsDo(AddressVisitor oopVisitor, RegisterMap map) { | |
447 if (isInterpretedFrame()) { | |
448 oopsInterpretedDo(oopVisitor, map); | |
449 } else if (isEntryFrame()) { | |
450 oopsEntryDo(oopVisitor, map); | |
451 } else if (VM.getVM().getCodeCache().contains(getPC())) { | |
452 oopsCodeBlobDo(oopVisitor, map); | |
453 } else { | |
454 Assert.that(false, "should not reach here"); | |
455 } | |
456 } | |
457 | |
458 //-------------------------------------------------------------------------------- | |
459 // Printing code | |
460 // | |
461 | |
462 public void printValue() { | |
463 printValueOn(System.out); | |
464 } | |
465 | |
466 public void printValueOn(PrintStream tty) { | |
467 // FIXME; | |
468 } | |
469 | |
470 public void print() { | |
471 printOn(System.out); | |
472 } | |
473 | |
474 public void printOn(PrintStream tty) { | |
475 // FIXME; | |
476 } | |
477 | |
478 public void interpreterFramePrintOn(PrintStream tty) { | |
479 // FIXME; | |
480 } | |
481 | |
482 //-------------------------------------------------------------------------------- | |
483 // Get/set typed locals from a frame. | |
484 // Respects platform dependent word-ordering. | |
485 // | |
486 // FIXME: avoiding implementing this for now if possible | |
487 // | |
488 // Currently these work only for interpreted frames. | |
489 // Todo: make these work for compiled frames. | |
490 // | |
491 // oop get_local_object(jint slot) const; | |
492 // jint get_local_int (jint slot) const; | |
493 // jlong get_local_long (jint slot) const; | |
494 // jfloat get_local_float (jint slot) const; | |
495 // jdouble get_local_double(jint slot) const; | |
496 // | |
497 // void set_local_object(jint slot, oop obj); | |
498 // void set_local_int (jint slot, jint i); | |
499 // void set_local_long (jint slot, jlong l); | |
500 // void set_local_float (jint slot, jfloat f); | |
501 // void set_local_double(jint slot, jdouble d); | |
502 | |
503 // FIXME: add safepoint code, oops_do, etc. | |
504 // FIXME: NOT FINISHED | |
505 | |
506 | |
507 | |
508 | |
509 | |
510 //-------------------------------------------------------------------------------- | |
511 // Internals only below this point | |
512 // | |
513 | |
514 // /** Helper method for better factored code in frame::sender */ | |
515 // private frame sender_for_entry_frame(RegisterMap* map) { throw new RuntimeException("not yet implemented"); } | |
516 // private frame sender_for_interpreter_frame(RegisterMap* map) { throw new RuntimeException("not yet implemented"); } | |
517 | |
518 // | |
519 // Oop iteration (FIXME: NOT FINISHED) | |
520 // | |
521 | |
522 | |
523 private static class InterpVisitor implements OopMapVisitor { | |
524 private AddressVisitor addressVisitor; | |
525 | |
526 public InterpVisitor(AddressVisitor oopVisitor) { | |
527 setAddressVisitor(oopVisitor); | |
528 } | |
529 | |
530 public void setAddressVisitor(AddressVisitor addressVisitor) { | |
531 this.addressVisitor = addressVisitor; | |
532 } | |
533 | |
534 public void visitOopLocation(Address oopAddr) { | |
535 addressVisitor.visitAddress(oopAddr); | |
536 } | |
537 | |
538 public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr) { | |
539 if (VM.getVM().isClientCompiler()) { | |
540 Assert.that(false, "should not reach here"); | |
541 } else if (VM.getVM().isServerCompiler() && | |
542 VM.getVM().useDerivedPointerTable()) { | |
543 Assert.that(false, "FIXME: add derived pointer table"); | |
544 } | |
545 } | |
546 | |
547 public void visitValueLocation(Address valueAddr) { | |
548 } | |
549 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
550 public void visitNarrowOopLocation(Address compOopAddr) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
551 addressVisitor.visitCompOopAddress(compOopAddr); |
0 | 552 } |
553 } | |
554 | |
555 private void oopsInterpretedDo(AddressVisitor oopVisitor, RegisterMap map) { | |
556 if (Assert.ASSERTS_ENABLED) { | |
557 Assert.that(map != null, "map must be set"); | |
558 } | |
559 Method m = getInterpreterFrameMethod(); | |
560 int bci = getInterpreterFrameBCI(); | |
561 | |
562 // FIXME: Seeing this sometimes | |
563 if (VM.getVM().isDebugging()) { | |
564 if (bci < 0 || bci >= m.getCodeSize()) return; | |
565 } | |
566 | |
567 if (Assert.ASSERTS_ENABLED) { | |
568 // Assert.that(VM.getVM().getUniverse().heap().isIn(m), "method must be valid oop"); | |
569 Assert.that((m.isNative() && (bci == 0)) || ((bci >= 0) && (bci < m.getCodeSize())), "invalid bci value"); | |
570 } | |
571 | |
572 // Handle the monitor elements in the activation | |
573 // FIXME: monitor information not yet exposed | |
574 // for ( | |
575 // BasicObjectLock* current = interpreter_frame_monitor_end(); | |
576 // current < interpreter_frame_monitor_begin(); | |
577 // current = next_monitor_in_interpreter_frame(current) | |
578 // ) { | |
579 //#ifdef ASSERT | |
580 // interpreter_frame_verify_monitor(current); | |
581 //#endif | |
582 // current->oops_do(f); | |
583 // } | |
584 | |
585 // process fixed part | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
586 // FIXME: these are no longer oops, so should anything be visitied? |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
587 // oopVisitor.visitAddress(addressOfInterpreterFrameMethod()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
588 // oopVisitor.visitAddress(addressOfInterpreterFrameCPCache()); |
0 | 589 |
590 // FIXME: expose interpreterFrameMirrorOffset | |
591 // if (m.isNative() && m.isStatic()) { | |
592 // oopVisitor.visitAddress(getFP().addOffsetTo(interpreterFrameMirrorOffset)); | |
593 // } | |
594 | |
595 int maxLocals = (int) (m.isNative() ? m.getSizeOfParameters() : m.getMaxLocals()); | |
596 InterpreterFrameClosure blk = new InterpreterFrameClosure(this, maxLocals, (int) m.getMaxStack(), oopVisitor); | |
597 | |
598 // process locals & expression stack | |
599 OopMapCacheEntry mask = m.getMaskFor(bci); | |
600 mask.iterateOop(blk); | |
601 | |
602 // process a callee's arguments if we are at a call site | |
603 // (i.e., if we are at an invoke bytecode) | |
604 if (map.getIncludeArgumentOops() && !m.isNative()) { | |
605 BytecodeInvoke call = BytecodeInvoke.atCheck(m, bci); | |
606 if (call != null && getInterpreterFrameExpressionStackSize() > 0) { | |
607 // we are at a call site & the expression stack is not empty | |
608 // => process callee's arguments | |
609 // | |
610 // Note: The expression stack can be empty if an exception | |
611 // occured during method resolution/execution. In all | |
612 // cases we empty the expression stack completely be- | |
613 // fore handling the exception (the exception handling | |
614 // code in the interpreter calls a blocking runtime | |
615 // routine which can cause this code to be executed). | |
616 // (was bug gri 7/27/98) | |
617 oopsInterpretedArgumentsDo(call.signature(), call.isInvokestatic(), oopVisitor); | |
618 } | |
619 } | |
620 } | |
621 | |
622 private void oopsEntryDo (AddressVisitor oopVisitor, RegisterMap regMap) {} | |
623 private void oopsCodeBlobDo (AddressVisitor oopVisitor, RegisterMap regMap) { | |
624 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); | |
625 if (Assert.ASSERTS_ENABLED) { | |
626 Assert.that(cb != null, "sanity check"); | |
627 } | |
628 if (cb.getOopMaps() != null) { | |
629 OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging()); | |
630 | |
631 // FIXME: add in traversal of argument oops (skipping this for | |
632 // now until we have the other stuff tested) | |
633 | |
634 } | |
635 | |
636 // FIXME: would add this in in non-debugging system | |
637 | |
638 // If we see an activation belonging to a non_entrant nmethod, we mark it. | |
639 // if (cb->is_nmethod() && ((nmethod *)cb)->is_not_entrant()) { | |
640 // ((nmethod*)cb)->mark_as_seen_on_stack(); | |
641 // } | |
642 } | |
643 | |
644 // FIXME: implement the above routines, plus add | |
645 // oops_interpreted_arguments_do and oops_compiled_arguments_do | |
646 } | |
647 | |
648 // | |
649 // Only used internally, to iterate through oop slots in interpreted | |
650 // frames | |
651 // | |
652 class InterpreterFrameClosure implements OffsetClosure { | |
653 // Used for debugging this code | |
654 private static final boolean DEBUG = false; | |
655 | |
656 private Frame fr; | |
657 private AddressVisitor f; | |
658 private int maxLocals; | |
659 private int maxStack; | |
660 | |
661 InterpreterFrameClosure(Frame fr, int maxLocals, int maxStack, AddressVisitor f) { | |
662 this.fr = fr; | |
663 this.maxLocals = maxLocals; | |
664 this.maxStack = maxStack; | |
665 this.f = f; | |
666 } | |
667 | |
668 public void offsetDo(int offset) { | |
669 if (DEBUG) { | |
670 System.err.println("Visiting offset " + offset + ", maxLocals = " + maxLocals + | |
671 " for frame " + fr + ", method " + | |
672 fr.getInterpreterFrameMethod().getMethodHolder().getName().asString() + | |
673 fr.getInterpreterFrameMethod().getName().asString()); | |
674 } | |
675 Address addr; | |
676 if (offset < maxLocals) { | |
677 addr = fr.addressOfInterpreterFrameLocal(offset); | |
678 if (Assert.ASSERTS_ENABLED) { | |
679 Assert.that(AddressOps.gte(addr, fr.getSP()), "must be inside the frame"); | |
680 } | |
681 if (DEBUG) { | |
682 System.err.println(" Visiting local at addr " + addr); | |
683 } | |
684 f.visitAddress(addr); | |
685 } else { | |
686 addr = fr.addressOfInterpreterFrameExpressionStackSlot(offset - maxLocals); | |
687 if (DEBUG) { | |
688 System.err.println(" Address of expression stack slot: " + addr + ", TOS = " + | |
689 fr.addressOfInterpreterFrameTOS()); | |
690 } | |
691 // In case of exceptions, the expression stack is invalid and the esp will be reset to express | |
692 // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel). | |
693 boolean inStack; | |
694 if (fr.getInterpreterFrameExpressionStackDirection() > 0) { | |
695 inStack = AddressOps.lte(addr, fr.addressOfInterpreterFrameTOS()); | |
696 } else { | |
697 inStack = AddressOps.gte(addr, fr.addressOfInterpreterFrameTOS()); | |
698 } | |
699 if (inStack) { | |
700 if (DEBUG) { | |
701 System.err.println(" In stack; visiting location."); | |
702 } | |
703 f.visitAddress(addr); | |
704 } else if (DEBUG) { | |
705 System.err.println(" *** WARNING: Address is out of bounds"); | |
706 } | |
707 } | |
708 } | |
709 } | |
710 | |
711 // Only used internally, to find arguments in interpreted frames | |
712 class ArgumentOopFinder extends SignatureInfo { | |
713 private AddressVisitor f; | |
714 private int offset; | |
715 private boolean isStatic; | |
716 private Frame fr; | |
717 | |
718 protected void set(int size, int type) { | |
719 offset -= size; | |
720 if (type == BasicType.getTObject() || type == BasicType.getTArray()) oopOffsetDo(); | |
721 } | |
722 | |
723 private void oopOffsetDo() { | |
724 f.visitAddress(fr.addressOfInterpreterFrameTOSAt(offset)); | |
725 } | |
726 | |
727 public ArgumentOopFinder(Symbol signature, boolean isStatic, Frame fr, AddressVisitor f) { | |
728 super(signature); | |
729 | |
730 // compute size of arguments | |
731 int argsSize = new ArgumentSizeComputer(signature).size() + (isStatic ? 0 : 1); | |
732 if (Assert.ASSERTS_ENABLED) { | |
733 Assert.that(!fr.isInterpretedFrame() || | |
734 argsSize <= fr.getInterpreterFrameExpressionStackSize(), "args cannot be on stack anymore"); | |
735 } | |
736 // initialize ArgumentOopFinder | |
737 this.f = f; | |
738 this.fr = fr; | |
739 this.offset = argsSize; | |
740 this.isStatic = isStatic; | |
741 } | |
742 | |
743 public void oopsDo() { | |
744 if (!isStatic) { | |
745 --offset; | |
746 oopOffsetDo(); | |
747 } | |
748 iterateParameters(); | |
749 } | |
750 } |