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