Mercurial > hg > graal-jvmci-8
annotate agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java @ 1552:c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
Summary: Change all the Sun copyrights to Oracle copyright
Reviewed-by: ohair
author | trims |
---|---|
date | Thu, 27 May 2010 19:08:38 -0700 |
parents | a61af66fc99e |
children | 7588156f5cf9 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2001, 2006, 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:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
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:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.runtime.x86; | |
26 | |
27 import java.util.*; | |
28 import sun.jvm.hotspot.asm.x86.*; | |
29 import sun.jvm.hotspot.code.*; | |
30 import sun.jvm.hotspot.compiler.*; | |
31 import sun.jvm.hotspot.debugger.*; | |
32 import sun.jvm.hotspot.oops.*; | |
33 import sun.jvm.hotspot.runtime.*; | |
34 import sun.jvm.hotspot.types.*; | |
35 import sun.jvm.hotspot.utilities.*; | |
36 | |
37 /** Specialization of and implementation of abstract methods of the | |
38 Frame class for the x86 family of CPUs. */ | |
39 | |
40 public class X86Frame extends Frame { | |
41 private static final boolean DEBUG; | |
42 static { | |
43 DEBUG = System.getProperty("sun.jvm.hotspot.runtime.x86.X86Frame.DEBUG") != null; | |
44 } | |
45 | |
46 // All frames | |
47 private static final int LINK_OFFSET = 0; | |
48 private static final int RETURN_ADDR_OFFSET = 1; | |
49 private static final int SENDER_SP_OFFSET = 2; | |
50 | |
51 // Interpreter frames | |
52 private static final int INTERPRETER_FRAME_MIRROR_OFFSET = 2; // for native calls only | |
53 private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1; | |
54 private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1; | |
55 private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET - 1; | |
56 private static int INTERPRETER_FRAME_MDX_OFFSET; // Non-core builds only | |
57 private static int INTERPRETER_FRAME_CACHE_OFFSET; | |
58 private static int INTERPRETER_FRAME_LOCALS_OFFSET; | |
59 private static int INTERPRETER_FRAME_BCX_OFFSET; | |
60 private static int INTERPRETER_FRAME_INITIAL_SP_OFFSET; | |
61 private static int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET; | |
62 private static int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET; | |
63 | |
64 // Entry frames | |
65 private static final int ENTRY_FRAME_CALL_WRAPPER_OFFSET = 2; | |
66 | |
67 // Native frames | |
68 private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET = 2; | |
69 | |
70 static { | |
71 VM.registerVMInitializedObserver(new Observer() { | |
72 public void update(Observable o, Object data) { | |
73 initialize(VM.getVM().getTypeDataBase()); | |
74 } | |
75 }); | |
76 } | |
77 | |
78 private static synchronized void initialize(TypeDataBase db) { | |
79 if (VM.getVM().isCore()) { | |
80 INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1; | |
81 } else { | |
82 INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1; | |
83 INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1; | |
84 } | |
85 INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1; | |
86 INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1; | |
87 INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; | |
88 INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; | |
89 INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; | |
90 } | |
91 | |
92 // an additional field beyond sp and pc: | |
93 Address raw_fp; // frame pointer | |
94 private Address raw_unextendedSP; | |
95 | |
96 private X86Frame() { | |
97 } | |
98 | |
99 private void adjustForDeopt() { | |
100 if ( pc != null) { | |
101 // Look for a deopt pc and if it is deopted convert to original pc | |
102 CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc); | |
103 if (cb != null && cb.isJavaMethod()) { | |
104 NMethod nm = (NMethod) cb; | |
105 if (pc.equals(nm.deoptBegin())) { | |
106 if (Assert.ASSERTS_ENABLED) { | |
107 Assert.that(this.getUnextendedSP() != null, "null SP in Java frame"); | |
108 } | |
109 // adjust pc if frame is deoptimized. | |
110 pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset()); | |
111 deoptimized = true; | |
112 } | |
113 } | |
114 } | |
115 } | |
116 | |
117 public X86Frame(Address raw_sp, Address raw_fp, Address pc) { | |
118 this.raw_sp = raw_sp; | |
119 this.raw_unextendedSP = raw_sp; | |
120 this.raw_fp = raw_fp; | |
121 this.pc = pc; | |
122 | |
123 // Frame must be fully constructed before this call | |
124 adjustForDeopt(); | |
125 | |
126 if (DEBUG) { | |
127 System.out.println("X86Frame(sp, fp, pc): " + this); | |
128 dumpStack(); | |
129 } | |
130 } | |
131 | |
132 public X86Frame(Address raw_sp, Address raw_fp) { | |
133 this.raw_sp = raw_sp; | |
134 this.raw_unextendedSP = raw_sp; | |
135 this.raw_fp = raw_fp; | |
136 this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize()); | |
137 | |
138 // Frame must be fully constructed before this call | |
139 adjustForDeopt(); | |
140 | |
141 if (DEBUG) { | |
142 System.out.println("X86Frame(sp, fp): " + this); | |
143 dumpStack(); | |
144 } | |
145 } | |
146 | |
147 // This constructor should really take the unextended SP as an arg | |
148 // but then the constructor is ambiguous with constructor that takes | |
149 // a PC so take an int and convert it. | |
150 public X86Frame(Address raw_sp, Address raw_fp, long extension) { | |
151 this.raw_sp = raw_sp; | |
152 if (raw_sp == null) { | |
153 this.raw_unextendedSP = null; | |
154 } else { | |
155 this.raw_unextendedSP = raw_sp.addOffsetTo(extension); | |
156 } | |
157 this.raw_fp = raw_fp; | |
158 this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize()); | |
159 | |
160 // Frame must be fully constructed before this call | |
161 adjustForDeopt(); | |
162 | |
163 if (DEBUG) { | |
164 System.out.println("X86Frame(sp, fp): " + this); | |
165 dumpStack(); | |
166 } | |
167 | |
168 } | |
169 | |
170 public Object clone() { | |
171 X86Frame frame = new X86Frame(); | |
172 frame.raw_sp = raw_sp; | |
173 frame.raw_unextendedSP = raw_unextendedSP; | |
174 frame.raw_fp = raw_fp; | |
175 frame.raw_fp = raw_fp; | |
176 frame.pc = pc; | |
177 frame.deoptimized = deoptimized; | |
178 return frame; | |
179 } | |
180 | |
181 public boolean equals(Object arg) { | |
182 if (arg == null) { | |
183 return false; | |
184 } | |
185 | |
186 if (!(arg instanceof X86Frame)) { | |
187 return false; | |
188 } | |
189 | |
190 X86Frame other = (X86Frame) arg; | |
191 | |
192 return (AddressOps.equal(getSP(), other.getSP()) && | |
193 AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) && | |
194 AddressOps.equal(getFP(), other.getFP()) && | |
195 AddressOps.equal(getPC(), other.getPC())); | |
196 } | |
197 | |
198 public int hashCode() { | |
199 if (raw_sp == null) { | |
200 return 0; | |
201 } | |
202 | |
203 return raw_sp.hashCode(); | |
204 } | |
205 | |
206 public String toString() { | |
207 return "sp: " + (getSP() == null? "null" : getSP().toString()) + | |
208 ", unextendedSP: " + (getUnextendedSP() == null? "null" : getUnextendedSP().toString()) + | |
209 ", fp: " + (getFP() == null? "null" : getFP().toString()) + | |
210 ", pc: " + (pc == null? "null" : pc.toString()); | |
211 } | |
212 | |
213 // accessors for the instance variables | |
214 public Address getFP() { return raw_fp; } | |
215 public Address getSP() { return raw_sp; } | |
216 public Address getID() { return raw_sp; } | |
217 | |
218 // FIXME: not implemented yet (should be done for Solaris/X86) | |
219 public boolean isSignalHandlerFrameDbg() { return false; } | |
220 public int getSignalNumberDbg() { return 0; } | |
221 public String getSignalNameDbg() { return null; } | |
222 | |
223 public boolean isInterpretedFrameValid() { | |
224 if (Assert.ASSERTS_ENABLED) { | |
225 Assert.that(isInterpretedFrame(), "Not an interpreted frame"); | |
226 } | |
227 | |
228 // These are reasonable sanity checks | |
229 if (getFP() == null || getFP().andWithMask(0x3) != null) { | |
230 return false; | |
231 } | |
232 | |
233 if (getSP() == null || getSP().andWithMask(0x3) != null) { | |
234 return false; | |
235 } | |
236 | |
237 if (getFP().addOffsetTo(INTERPRETER_FRAME_INITIAL_SP_OFFSET * VM.getVM().getAddressSize()).lessThan(getSP())) { | |
238 return false; | |
239 } | |
240 | |
241 // These are hacks to keep us out of trouble. | |
242 // The problem with these is that they mask other problems | |
243 if (getFP().lessThanOrEqual(getSP())) { | |
244 // this attempts to deal with unsigned comparison above | |
245 return false; | |
246 } | |
247 | |
248 if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) { | |
249 // stack frames shouldn't be large. | |
250 return false; | |
251 } | |
252 | |
253 return true; | |
254 } | |
255 | |
256 // FIXME: not applicable in current system | |
257 // void patch_pc(Thread* thread, address pc); | |
258 | |
259 public Frame sender(RegisterMap regMap, CodeBlob cb) { | |
260 X86RegisterMap map = (X86RegisterMap) regMap; | |
261 | |
262 if (Assert.ASSERTS_ENABLED) { | |
263 Assert.that(map != null, "map must be set"); | |
264 } | |
265 | |
266 // Default is we done have to follow them. The sender_for_xxx will | |
267 // update it accordingly | |
268 map.setIncludeArgumentOops(false); | |
269 | |
270 if (isEntryFrame()) return senderForEntryFrame(map); | |
271 if (isInterpretedFrame()) return senderForInterpreterFrame(map); | |
272 | |
273 if (!VM.getVM().isCore()) { | |
274 if(cb == null) { | |
275 cb = VM.getVM().getCodeCache().findBlob(getPC()); | |
276 } else { | |
277 if (Assert.ASSERTS_ENABLED) { | |
278 Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same"); | |
279 } | |
280 } | |
281 | |
282 if (cb != null) { | |
283 return senderForCompiledFrame(map, cb); | |
284 } | |
285 } | |
286 | |
287 // Must be native-compiled frame, i.e. the marshaling code for native | |
288 // methods that exists in the core system. | |
289 return new X86Frame(getSenderSP(), getLink(), getSenderPC()); | |
290 } | |
291 | |
292 private Frame senderForEntryFrame(X86RegisterMap map) { | |
293 if (Assert.ASSERTS_ENABLED) { | |
294 Assert.that(map != null, "map must be set"); | |
295 } | |
296 // Java frame called from C; skip all C frames and return top C | |
297 // frame of that chunk as the sender | |
298 X86JavaCallWrapper jcw = (X86JavaCallWrapper) getEntryFrameCallWrapper(); | |
299 if (Assert.ASSERTS_ENABLED) { | |
300 Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero"); | |
301 Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack"); | |
302 } | |
303 X86Frame fr; | |
304 if (jcw.getLastJavaPC() != null) { | |
305 fr = new X86Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC()); | |
306 } else { | |
307 fr = new X86Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP()); | |
308 } | |
309 map.clear(); | |
310 if (Assert.ASSERTS_ENABLED) { | |
311 Assert.that(map.getIncludeArgumentOops(), "should be set by clear"); | |
312 } | |
313 return fr; | |
314 } | |
315 | |
316 private Frame senderForInterpreterFrame(X86RegisterMap map) { | |
317 Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0); | |
318 Address sp = addressOfStackSlot(SENDER_SP_OFFSET); | |
319 // We do not need to update the callee-save register mapping because above | |
320 // us is either another interpreter frame or a converter-frame, but never | |
321 // directly a compiled frame. | |
322 // 11/24/04 SFG. With the removal of adapter frames this is no longer true. | |
323 // However c2 no longer uses callee save register for java calls so there | |
324 // are no callee register to find. | |
325 | |
326 return new X86Frame(sp, getLink(), unextendedSP.minus(sp)); | |
327 } | |
328 | |
329 private Frame senderForCompiledFrame(X86RegisterMap map, CodeBlob cb) { | |
330 // | |
331 // NOTE: some of this code is (unfortunately) duplicated in X86CurrentFrameGuess | |
332 // | |
333 | |
334 if (Assert.ASSERTS_ENABLED) { | |
335 Assert.that(map != null, "map must be set"); | |
336 } | |
337 | |
338 // frame owned by optimizing compiler | |
339 Address sender_sp = null; | |
340 | |
341 if (VM.getVM().isClientCompiler()) { | |
342 sender_sp = addressOfStackSlot(SENDER_SP_OFFSET); | |
343 } else { | |
344 if (Assert.ASSERTS_ENABLED) { | |
345 Assert.that(cb.getFrameSize() >= 0, "Compiled by Compiler1: do not use"); | |
346 } | |
347 sender_sp = getUnextendedSP().addOffsetTo(cb.getFrameSize()); | |
348 } | |
349 | |
350 // On Intel the return_address is always the word on the stack | |
351 Address sender_pc = sender_sp.getAddressAt(-1 * VM.getVM().getAddressSize()); | |
352 | |
353 if (map.getUpdateMap() && cb.getOopMaps() != null) { | |
354 OopMapSet.updateRegisterMap(this, cb, map, true); | |
355 } | |
356 | |
357 if (VM.getVM().isClientCompiler()) { | |
358 // Move this here for C1 and collecting oops in arguments (According to Rene) | |
359 map.setIncludeArgumentOops(cb.callerMustGCArguments(map.getThread())); | |
360 } | |
361 | |
362 Address saved_fp = null; | |
363 if (VM.getVM().isClientCompiler()) { | |
364 saved_fp = getFP().getAddressAt(0); | |
365 } else if (VM.getVM().isServerCompiler() && | |
366 (VM.getVM().getInterpreter().contains(sender_pc) || | |
367 VM.getVM().getStubRoutines().returnsToCallStub(sender_pc))) { | |
368 // C2 prologue saves EBP in the usual place. | |
369 // however only use it if the sender had link infomration in it. | |
370 saved_fp = sender_sp.getAddressAt(-2 * VM.getVM().getAddressSize()); | |
371 } | |
372 | |
373 return new X86Frame(sender_sp, saved_fp, sender_pc); | |
374 } | |
375 | |
376 protected boolean hasSenderPD() { | |
377 // FIXME | |
378 // Check for null ebp? Need to do some tests. | |
379 return true; | |
380 } | |
381 | |
382 public long frameSize() { | |
383 return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize()); | |
384 } | |
385 | |
386 public Address getLink() { | |
387 return addressOfStackSlot(LINK_OFFSET).getAddressAt(0); | |
388 } | |
389 | |
390 // FIXME: not implementable yet | |
391 //inline void frame::set_link(intptr_t* addr) { *(intptr_t **)addr_at(link_offset) = addr; } | |
392 | |
393 public Address getUnextendedSP() { return raw_unextendedSP; } | |
394 | |
395 // Return address: | |
396 public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); } | |
397 public Address getSenderPC() { return getSenderPCAddr().getAddressAt(0); } | |
398 | |
399 // return address of param, zero origin index. | |
400 public Address getNativeParamAddr(int idx) { | |
401 return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx); | |
402 } | |
403 | |
404 public Address getSenderSP() { return addressOfStackSlot(SENDER_SP_OFFSET); } | |
405 | |
406 public Address compiledArgumentToLocationPD(VMReg reg, RegisterMap regMap, int argSize) { | |
407 if (VM.getVM().isCore() || VM.getVM().isClientCompiler()) { | |
408 throw new RuntimeException("Should not reach here"); | |
409 } | |
410 | |
411 return oopMapRegToLocation(reg, regMap); | |
412 } | |
413 | |
414 public Address addressOfInterpreterFrameLocals() { | |
415 return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET); | |
416 } | |
417 | |
418 private Address addressOfInterpreterFrameBCX() { | |
419 return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET); | |
420 } | |
421 | |
422 public int getInterpreterFrameBCI() { | |
423 // FIXME: this is not atomic with respect to GC and is unsuitable | |
424 // for use in a non-debugging, or reflective, system. Need to | |
425 // figure out how to express this. | |
426 Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0); | |
427 OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0); | |
428 Method method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle); | |
429 return bcpToBci(bcp, method); | |
430 } | |
431 | |
432 public Address addressOfInterpreterFrameMDX() { | |
433 return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET); | |
434 } | |
435 | |
436 // FIXME | |
437 //inline int frame::interpreter_frame_monitor_size() { | |
438 // return BasicObjectLock::size(); | |
439 //} | |
440 | |
441 // expression stack | |
442 // (the max_stack arguments are used by the GC; see class FrameClosure) | |
443 | |
444 public Address addressOfInterpreterFrameExpressionStack() { | |
445 Address monitorEnd = interpreterFrameMonitorEnd().address(); | |
446 return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize()); | |
447 } | |
448 | |
449 public int getInterpreterFrameExpressionStackDirection() { return -1; } | |
450 | |
451 // top of expression stack | |
452 public Address addressOfInterpreterFrameTOS() { | |
453 return getSP(); | |
454 } | |
455 | |
456 /** Expression stack from top down */ | |
457 public Address addressOfInterpreterFrameTOSAt(int slot) { | |
458 return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize()); | |
459 } | |
460 | |
461 public Address getInterpreterFrameSenderSP() { | |
462 if (Assert.ASSERTS_ENABLED) { | |
463 Assert.that(isInterpretedFrame(), "interpreted frame expected"); | |
464 } | |
465 return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0); | |
466 } | |
467 | |
468 // Monitors | |
469 public BasicObjectLock interpreterFrameMonitorBegin() { | |
470 return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET)); | |
471 } | |
472 | |
473 public BasicObjectLock interpreterFrameMonitorEnd() { | |
474 Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0); | |
475 if (Assert.ASSERTS_ENABLED) { | |
476 // make sure the pointer points inside the frame | |
477 Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer"); | |
478 Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer"); | |
479 } | |
480 return new BasicObjectLock(result); | |
481 } | |
482 | |
483 public int interpreterFrameMonitorSize() { | |
484 return BasicObjectLock.size(); | |
485 } | |
486 | |
487 // Method | |
488 public Address addressOfInterpreterFrameMethod() { | |
489 return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET); | |
490 } | |
491 | |
492 // Constant pool cache | |
493 public Address addressOfInterpreterFrameCPCache() { | |
494 return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET); | |
495 } | |
496 | |
497 // Entry frames | |
498 public JavaCallWrapper getEntryFrameCallWrapper() { | |
499 return new X86JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0)); | |
500 } | |
501 | |
502 protected Address addressOfSavedOopResult() { | |
503 // offset is 2 for compiler2 and 3 for compiler1 | |
504 return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) * | |
505 VM.getVM().getAddressSize()); | |
506 } | |
507 | |
508 protected Address addressOfSavedReceiver() { | |
509 return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize()); | |
510 } | |
511 | |
512 private void dumpStack() { | |
513 if (getFP() != null) { | |
514 for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize()); | |
515 AddressOps.lte(addr, getFP().addOffsetTo(5 * VM.getVM().getAddressSize())); | |
516 addr = addr.addOffsetTo(VM.getVM().getAddressSize())) { | |
517 System.out.println(addr + ": " + addr.getAddressAt(0)); | |
518 } | |
519 } else { | |
520 for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize()); | |
521 AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize())); | |
522 addr = addr.addOffsetTo(VM.getVM().getAddressSize())) { | |
523 System.out.println(addr + ": " + addr.getAddressAt(0)); | |
524 } | |
525 } | |
526 } | |
527 } |