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