0
|
1 /*
|
|
2 * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
|
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.ia64;
|
|
26
|
|
27 import java.util.*;
|
|
28 // import sun.jvm.hotspot.asm.ia64.*;
|
|
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 ia64 family of CPUs. */
|
|
39
|
|
40 public class IA64Frame extends Frame {
|
|
41 private static final boolean DEBUG = false;
|
|
42
|
|
43 // All frames
|
|
44
|
|
45 // Interpreter frames
|
|
46
|
|
47 // Entry frames
|
|
48
|
|
49 // Native frames
|
|
50
|
|
51 // an additional field beyond sp and pc:
|
|
52 // Address raw_fp; // frame pointer only 1.4.2
|
|
53
|
|
54 Address iframe;
|
|
55
|
|
56 private IA64Frame() {
|
|
57 }
|
|
58
|
|
59 public IA64Frame(Address raw_sp, Address iframe, Address pc) {
|
|
60 this.raw_sp = raw_sp;
|
|
61 this.iframe = iframe;
|
|
62 this.pc = pc;
|
|
63 if (DEBUG) {
|
|
64 System.err.println("IA64Frame(sp, iframe, pc): " + this);
|
|
65 dumpStack();
|
|
66 }
|
|
67 }
|
|
68
|
|
69 public Object clone() {
|
|
70 IA64Frame frame = new IA64Frame();
|
|
71 frame.raw_sp = raw_sp;
|
|
72 frame.iframe = iframe;
|
|
73 frame.pc = pc;
|
|
74 return frame;
|
|
75 }
|
|
76
|
|
77 public boolean equals(Object arg) {
|
|
78 if (arg == null) {
|
|
79 return false;
|
|
80 }
|
|
81
|
|
82 if (!(arg instanceof IA64Frame)) {
|
|
83 return false;
|
|
84 }
|
|
85
|
|
86 IA64Frame other = (IA64Frame) arg;
|
|
87
|
|
88 return (AddressOps.equal(getSP(), other.getSP()) &&
|
|
89 AddressOps.equal(getIFRAME(), other.getIFRAME()) &&
|
|
90 AddressOps.equal(getPC(), other.getPC()));
|
|
91 }
|
|
92
|
|
93 public int hashCode() {
|
|
94 if (iframe == null) {
|
|
95 return 0;
|
|
96 }
|
|
97
|
|
98 return iframe.hashCode();
|
|
99 }
|
|
100
|
|
101 public String toString() {
|
|
102 return "sp: " + (getSP() == null? "null" : getSP().toString()) +
|
|
103 ", iframe: " + (getIFRAME() == null? "null" : getIFRAME().toString()) +
|
|
104 ", pc: " + (pc == null? "null" : pc.toString());
|
|
105 }
|
|
106
|
|
107 // accessors for the instance variables
|
|
108 public Address getFP() { return null; }
|
|
109 public Address getIFRAME() { return iframe; }
|
|
110 public Address getSP() { return raw_sp; }
|
|
111 public Address getID() { return getFP(); }
|
|
112
|
|
113 // FIXME: not implemented yet
|
|
114 public boolean isSignalHandlerFrameDbg() { return false; }
|
|
115 public int getSignalNumberDbg() { return 0; }
|
|
116 public String getSignalNameDbg() { return null; }
|
|
117
|
|
118 // FIXME: do sanity checks
|
|
119 public boolean isInterpretedFrameValid() {
|
|
120 return true;
|
|
121 }
|
|
122
|
|
123 public boolean isInterpretedFrame() { return iframe != null; }
|
|
124
|
|
125
|
|
126 // FIXME: not applicable in current system
|
|
127 // void patch_pc(Thread* thread, address pc);
|
|
128
|
|
129 public Frame sender(RegisterMap regMap, CodeBlob cb) {
|
|
130
|
|
131 if (iframe == null) {
|
|
132 return null;
|
|
133 }
|
|
134
|
|
135 cInterpreter fr = new cInterpreter(iframe);
|
|
136
|
|
137 if (fr.prev() == null) {
|
|
138 Address wrapper = fr.wrapper();
|
|
139 if ( wrapper == null) {
|
|
140 return null;
|
|
141 }
|
|
142 IA64JavaCallWrapper jcw = new IA64JavaCallWrapper(wrapper);
|
|
143 Address iprev = jcw.getPrevIFrame();
|
|
144 if (iprev == null) {
|
|
145 return null;
|
|
146 }
|
|
147 return new IA64Frame(null, iprev, null);
|
|
148 } else {
|
|
149 return new IA64Frame(null, fr.prev(), null);
|
|
150 }
|
|
151
|
|
152 /*
|
|
153 IA64RegisterMap map = (IA64RegisterMap) regMap;
|
|
154
|
|
155 if (Assert.ASSERTS_ENABLED) {
|
|
156 Assert.that(map != null, "map must be set");
|
|
157 }
|
|
158
|
|
159 // Default is we done have to follow them. The sender_for_xxx will
|
|
160 // update it accordingly
|
|
161 map.setIncludeArgumentOops(false);
|
|
162
|
|
163 if (isEntryFrame()) return senderForEntryFrame(map);
|
|
164 if (isInterpretedFrame()) return senderForInterpreterFrame(map);
|
|
165
|
|
166 if (!VM.getVM().isCore()) {
|
|
167 if(cb == null) {
|
|
168 cb = VM.getVM().getCodeCache().findBlob(getPC());
|
|
169 } else {
|
|
170 if (Assert.ASSERTS_ENABLED) {
|
|
171 Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
|
|
172 }
|
|
173 }
|
|
174
|
|
175 if (cb != null) {
|
|
176 return senderForCompiledFrame(map, cb);
|
|
177 }
|
|
178 }
|
|
179
|
|
180 // Must be native-compiled frame, i.e. the marshaling code for native
|
|
181 // methods that exists in the core system.
|
|
182 return new IA64Frame(getSenderSP(), getLink(), getSenderPC());
|
|
183
|
|
184 */
|
|
185 }
|
|
186
|
|
187 private Frame senderForEntryFrame(IA64RegisterMap map) {
|
|
188 if (Assert.ASSERTS_ENABLED) {
|
|
189 Assert.that(map != null, "map must be set");
|
|
190 }
|
|
191 /*
|
|
192 // Java frame called from C; skip all C frames and return top C
|
|
193 // frame of that chunk as the sender
|
|
194 IA64JavaCallWrapper jcw = (IA64JavaCallWrapper) getEntryFrameCallWrapper();
|
|
195 if (Assert.ASSERTS_ENABLED) {
|
|
196 Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero");
|
|
197 Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack");
|
|
198 }
|
|
199 IA64Frame fr = new IA64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), null);
|
|
200 map.clear();
|
|
201 if (Assert.ASSERTS_ENABLED) {
|
|
202 Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
|
|
203 }
|
|
204 return fr;
|
|
205 */
|
|
206 throw new RuntimeException("senderForEntryFrame NYI");
|
|
207 }
|
|
208
|
|
209 private Frame senderForInterpreterFrame(IA64RegisterMap map) {
|
|
210 /*
|
|
211 Address sp = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
|
|
212 // We do not need to update the callee-save register mapping because above
|
|
213 // us is either another interpreter frame or a converter-frame, but never
|
|
214 // directly a compiled frame.
|
|
215 return new IA64Frame(sp, getLink(), getSenderPC());
|
|
216 */
|
|
217 throw new RuntimeException("senderForInterpreterFrame NYI");
|
|
218 }
|
|
219
|
|
220 private Frame senderForDeoptimizedFrame(IA64RegisterMap map, CodeBlob cb) {
|
|
221 // FIXME
|
|
222 throw new RuntimeException("Deoptimized frames not handled yet");
|
|
223 }
|
|
224
|
|
225 private Frame senderForCompiledFrame(IA64RegisterMap map, CodeBlob cb) {
|
|
226 //
|
|
227 // NOTE: some of this code is (unfortunately) duplicated in IA64CurrentFrameGuess
|
|
228 //
|
|
229
|
|
230 if (Assert.ASSERTS_ENABLED) {
|
|
231 Assert.that(map != null, "map must be set");
|
|
232 }
|
|
233
|
|
234 throw new RuntimeException("senderForCompiledFrame NYI");
|
|
235
|
|
236 /*
|
|
237
|
|
238 // frame owned by optimizing compiler
|
|
239 Address sender_sp = null;
|
|
240
|
|
241 if (VM.getVM().isClientCompiler()) {
|
|
242 sender_sp = addressOfStackSlot(SENDER_SP_OFFSET);
|
|
243 } else {
|
|
244 if (Assert.ASSERTS_ENABLED) {
|
|
245 Assert.that(cb.getFrameSize() >= 0, "Compiled by Compiler1: do not use");
|
|
246 }
|
|
247 sender_sp = getSP().addOffsetTo(cb.getFrameSize());
|
|
248 }
|
|
249
|
|
250 // On Intel the return_address is always the word on the stack
|
|
251 Address sender_pc = sender_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
|
|
252
|
|
253 if (map.getUpdateMap() && cb.getOopMaps() != null) {
|
|
254 OopMapSet.updateRegisterMap(this, cb, map, true);
|
|
255 }
|
|
256
|
|
257 Address saved_fp = null;
|
|
258 if (VM.getVM().isClientCompiler()) {
|
|
259 saved_fp = getFP().getAddressAt(0);
|
|
260 } else {
|
|
261 int llink_offset = cb.getLinkOffset();
|
|
262 if (llink_offset >= 0) {
|
|
263 // Restore base-pointer, since next frame might be an interpreter frame.
|
|
264 Address fp_addr = getSP().addOffsetTo(VM.getVM().getAddressSize() * llink_offset);
|
|
265 saved_fp = fp_addr.getAddressAt(0);
|
|
266 }
|
|
267 }
|
|
268
|
|
269 sender_sp = null ; // sp_addr.getAddressAt(0);
|
|
270
|
|
271 return new IA64Frame(sender_sp, saved_fp, sender_pc);
|
|
272
|
|
273 */
|
|
274 }
|
|
275
|
|
276 protected boolean hasSenderPD() {
|
|
277 // FIXME
|
|
278 return true;
|
|
279 }
|
|
280
|
|
281 public long frameSize() {
|
|
282 throw new RuntimeException("frameSize NYI");
|
|
283 /*
|
|
284 return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize());
|
|
285 */
|
|
286 }
|
|
287
|
|
288 public Address getLink() {
|
|
289 throw new RuntimeException("getLink NYI");
|
|
290 /*
|
|
291 return addressOfStackSlot(LINK_OFFSET).getAddressAt(0);
|
|
292 */
|
|
293 }
|
|
294
|
|
295 // FIXME: not implementable yet
|
|
296 //inline void frame::set_link(intptr_t* addr) { *(intptr_t **)addr_at(link_offset) = addr; }
|
|
297
|
|
298 public Address getUnextendedSP() { return getSP(); }
|
|
299
|
|
300 // Return address:
|
|
301 /*
|
|
302 public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); }
|
|
303 */
|
|
304
|
|
305 public Address getSenderPC() { return null; }
|
|
306
|
|
307 /*
|
|
308 // return address of param, zero origin index.
|
|
309 public Address getNativeParamAddr(int idx) {
|
|
310 return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx);
|
|
311 }
|
|
312 */
|
|
313
|
|
314 public Address getSenderSP() { return null; }
|
|
315
|
|
316 /*
|
|
317 public Address compiledArgumentToLocationPD(VMReg reg, RegisterMap regMap, int argSize) {
|
|
318 if (VM.getVM().isCore() || VM.getVM().isClientCompiler()) {
|
|
319 throw new RuntimeException("Should not reach here");
|
|
320 }
|
|
321
|
|
322 return oopMapRegToLocation(reg, regMap);
|
|
323 }
|
|
324
|
|
325 */
|
|
326
|
|
327 public Address addressOfInterpreterFrameLocals() {
|
|
328 if (iframe == null) {
|
|
329 throw new RuntimeException("Not an Interpreter frame");
|
|
330 }
|
|
331 cInterpreter fr = new cInterpreter(iframe);
|
|
332 return fr.locals();
|
|
333 }
|
|
334
|
|
335 private Address addressOfInterpreterFrameBCX() {
|
|
336 if (iframe == null) {
|
|
337 throw new RuntimeException("Not an Interpreter frame");
|
|
338 }
|
|
339 cInterpreter fr = new cInterpreter(iframe);
|
|
340 return fr.bcpAddr();
|
|
341 }
|
|
342
|
|
343 public int getInterpreterFrameBCI() {
|
|
344 // FIXME: this is not atomic with respect to GC and is unsuitable
|
|
345 // for use in a non-debugging, or reflective, system. Need to
|
|
346 // figure out how to express this.
|
|
347 Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
|
|
348 OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0);
|
|
349 Method method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle);
|
|
350 return bcpToBci(bcp, method);
|
|
351 }
|
|
352
|
|
353 public Address addressOfInterpreterFrameMDX() {
|
|
354 return null;
|
|
355 }
|
|
356
|
|
357 // FIXME
|
|
358 //inline int frame::interpreter_frame_monitor_size() {
|
|
359 // return BasicObjectLock::size();
|
|
360 //}
|
|
361
|
|
362 // expression stack
|
|
363 // (the max_stack arguments are used by the GC; see class FrameClosure)
|
|
364
|
|
365 public Address addressOfInterpreterFrameExpressionStack() {
|
|
366 if (iframe == null) {
|
|
367 throw new RuntimeException("Not an Interpreter frame");
|
|
368 }
|
|
369 cInterpreter fr = new cInterpreter(iframe);
|
|
370 return fr.stackBase();
|
|
371 }
|
|
372
|
|
373 public int getInterpreterFrameExpressionStackDirection() { return -1; }
|
|
374
|
|
375 // top of expression stack
|
|
376 public Address addressOfInterpreterFrameTOS() {
|
|
377 if (iframe == null) {
|
|
378 throw new RuntimeException("Not an Interpreter frame");
|
|
379 }
|
|
380 cInterpreter fr = new cInterpreter(iframe);
|
|
381 // tos always points to first free element in c++ interpreter not tos
|
|
382 return fr.stackBase().addOffsetTo(VM.getVM().getAddressSize());
|
|
383 }
|
|
384
|
|
385 /** Expression stack from top down */
|
|
386 public Address addressOfInterpreterFrameTOSAt(int slot) {
|
|
387 return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize());
|
|
388 }
|
|
389
|
|
390 public Address getInterpreterFrameSenderSP() {
|
|
391 if (Assert.ASSERTS_ENABLED) {
|
|
392 Assert.that(isInterpretedFrame(), "interpreted frame expected");
|
|
393 }
|
|
394 throw new RuntimeException("getInterpreterFrameSenderSP NYI");
|
|
395 }
|
|
396
|
|
397 // Monitors
|
|
398 public BasicObjectLock interpreterFrameMonitorBegin() {
|
|
399 if (iframe == null) {
|
|
400 throw new RuntimeException("Not an Interpreter frame");
|
|
401 }
|
|
402 cInterpreter fr = new cInterpreter(iframe);
|
|
403 return new BasicObjectLock(fr.monitorBase());
|
|
404 }
|
|
405
|
|
406 public BasicObjectLock interpreterFrameMonitorEnd() {
|
|
407 if (iframe == null) {
|
|
408 throw new RuntimeException("Not an Interpreter frame");
|
|
409 }
|
|
410 cInterpreter fr = new cInterpreter(iframe);
|
|
411 // Monitors end is just above stack base (2 slots per monitor)
|
|
412 Address result = fr.stackBase().addOffsetTo(2 * VM.getVM().getAddressSize());
|
|
413 /*
|
|
414 if (Assert.ASSERTS_ENABLED) {
|
|
415 // make sure the pointer points inside the frame
|
|
416 Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer");
|
|
417 Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer");
|
|
418 }
|
|
419 */
|
|
420 return new BasicObjectLock(result);
|
|
421 }
|
|
422
|
|
423 public int interpreterFrameMonitorSize() {
|
|
424 return BasicObjectLock.size();
|
|
425 }
|
|
426
|
|
427 // Method
|
|
428 public Address addressOfInterpreterFrameMethod() {
|
|
429 if (iframe == null) {
|
|
430 throw new RuntimeException("Not an Interpreter frame");
|
|
431 }
|
|
432 cInterpreter fr = new cInterpreter(iframe);
|
|
433 return fr.methodAddr();
|
|
434 }
|
|
435
|
|
436 // Constant pool cache
|
|
437 public Address addressOfInterpreterFrameCPCache() {
|
|
438 if (iframe == null) {
|
|
439 throw new RuntimeException("Not an Interpreter frame");
|
|
440 }
|
|
441 cInterpreter fr = new cInterpreter(iframe);
|
|
442 return fr.constantsAddr();
|
|
443 }
|
|
444
|
|
445 // Entry frames
|
|
446 public JavaCallWrapper getEntryFrameCallWrapper() {
|
|
447 throw new RuntimeException("getEntryFrameCallWrapper NYI");
|
|
448 }
|
|
449
|
|
450 protected Address addressOfSavedOopResult() {
|
|
451 throw new RuntimeException("public boolean isInterpretedFrame() NYI");
|
|
452 /*
|
|
453 // offset is 2 for compiler2 and 3 for compiler1
|
|
454 return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) *
|
|
455 VM.getVM().getAddressSize());
|
|
456 */
|
|
457 }
|
|
458
|
|
459 protected Address addressOfSavedReceiver() {
|
|
460 throw new RuntimeException("getEntryFrameCallWrapper NYI");
|
|
461 // return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
|
|
462 }
|
|
463
|
|
464 private void dumpStack() {
|
|
465 /*
|
|
466 if (getFP() != null) {
|
|
467 for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
|
|
468 AddressOps.lte(addr, getFP().addOffsetTo(5 * VM.getVM().getAddressSize()));
|
|
469 addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
|
|
470 System.out.println(addr + ": " + addr.getAddressAt(0));
|
|
471 }
|
|
472 } else {
|
|
473 for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
|
|
474 AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize()));
|
|
475 addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
|
|
476 System.out.println(addr + ": " + addr.getAddressAt(0));
|
|
477 }
|
|
478 }
|
|
479 */
|
|
480 }
|
|
481 }
|