130 public boolean isInterpretedFrame() { return VM.getVM().getInterpreter().contains(getPC()); }
131 public boolean isJavaFrame() {
132 if (isInterpretedFrame()) return true;
133 if (!VM.getVM().isCore()) {
134 if (isCompiledFrame()) return true;
135 }
136 return false;
137 }
138
139 /** Java frame called from C? */
140 public boolean isEntryFrame() { return VM.getVM().getStubRoutines().returnsToCallStub(getPC()); }
141 public boolean isNativeFrame() {
142 if (!VM.getVM().isCore()) {
143 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
144 return (cb != null && cb.isNativeMethod());
145 } else {
146 return false;
147 }
148 }
149
150 public boolean 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 public boolean isCompiledFrame() {
157 if (Assert.ASSERTS_ENABLED) {
158 Assert.that(!VM.getVM().isCore(), "noncore builds only");
159 }
160 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
161 return (cb != null && cb.isJavaMethod());
162 }
163
164 public boolean isRuntimeFrame() {
165 if (Assert.ASSERTS_ENABLED) {
166 Assert.that(!VM.getVM().isCore(), "noncore builds only");
167 }
168 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
169 if (cb == null) {
170 return false;
171 }
172 if (cb.isRuntimeStub()) return true;
173 else return false;
174 }
175
199
200 /** performs sanity checks on interpreted frames. */
201 public abstract boolean isInterpretedFrameValid();
202
203 /** tells whether this frame is marked for deoptimization */
204 public boolean shouldBeDeoptimized() { throw new RuntimeException("not yet implemented"); }
205
206 /** tells whether this frame can be deoptimized */
207 public boolean canBeDeoptimized() { throw new RuntimeException("not yet implemented"); }
208
209 /** returns the sending frame */
210 public abstract Frame sender(RegisterMap map, CodeBlob nm);
211
212 /** equivalent to sender(map, null) */
213 public Frame sender(RegisterMap map) { return sender(map, null); }
214
215 /** returns the sender, but skips conversion frames */
216 public Frame realSender(RegisterMap map) {
217 if (!VM.getVM().isCore()) {
218 Frame result = sender(map);
219 while (result.isRuntimeFrame() ||
220 result.isRicochetFrame()) {
221 result = result.sender(map);
222 }
223 return result;
224 } else {
225 return sender(map);
226 }
227 }
228
229 /** Platform-dependent query indicating whether this frame has a
230 sender. Should return true if it is possible to call sender() at
231 all on this frame. (This is currently only needed for the
232 debugging system, if a stack trace is attempted for a Java
233 thread which has no Java frames, i.e., the signal thread; we
234 have to know to stop traversal at the bottom frame.) */
235 protected abstract boolean hasSenderPD();
236
237 //--------------------------------------------------------------------------------
238 // All frames:
239 // A low-level interface for vframes:
240
614 // => process callee's arguments
615 //
616 // Note: The expression stack can be empty if an exception
617 // occured during method resolution/execution. In all
618 // cases we empty the expression stack completely be-
619 // fore handling the exception (the exception handling
620 // code in the interpreter calls a blocking runtime
621 // routine which can cause this code to be executed).
622 // (was bug gri 7/27/98)
623 oopsInterpretedArgumentsDo(call.signature(), call.isInvokestatic(), oopVisitor);
624 }
625 }
626 }
627
628 private void oopsEntryDo (AddressVisitor oopVisitor, RegisterMap regMap) {}
629 private void oopsCodeBlobDo (AddressVisitor oopVisitor, RegisterMap regMap) {
630 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
631 if (Assert.ASSERTS_ENABLED) {
632 Assert.that(cb != null, "sanity check");
633 }
634 if (cb == VM.getVM().ricochetBlob()) {
635 oopsRicochetDo(oopVisitor, regMap);
636 }
637 if (cb.getOopMaps() != null) {
638 OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
639
640 // FIXME: add in traversal of argument oops (skipping this for
641 // now until we have the other stuff tested)
642
643 }
644
645 // FIXME: would add this in in non-debugging system
646
647 // If we see an activation belonging to a non_entrant nmethod, we mark it.
648 // if (cb->is_nmethod() && ((nmethod *)cb)->is_not_entrant()) {
649 // ((nmethod*)cb)->mark_as_seen_on_stack();
650 // }
651 }
652
653 private void oopsRicochetDo (AddressVisitor oopVisitor, RegisterMap regMap) {
654 // XXX Empty for now
655 }
656
657 // FIXME: implement the above routines, plus add
658 // oops_interpreted_arguments_do and oops_compiled_arguments_do
659 }
660
661 //
662 // Only used internally, to iterate through oop slots in interpreted
663 // frames
664 //
665 class InterpreterFrameClosure implements OffsetClosure {
666 // Used for debugging this code
667 private static final boolean DEBUG = false;
668
669 private Frame fr;
670 private AddressVisitor f;
671 private int maxLocals;
672 private int maxStack;
673
674 InterpreterFrameClosure(Frame fr, int maxLocals, int maxStack, AddressVisitor f) {
675 this.fr = fr;
676 this.maxLocals = maxLocals;
|
130 public boolean isInterpretedFrame() { return VM.getVM().getInterpreter().contains(getPC()); }
131 public boolean isJavaFrame() {
132 if (isInterpretedFrame()) return true;
133 if (!VM.getVM().isCore()) {
134 if (isCompiledFrame()) return true;
135 }
136 return false;
137 }
138
139 /** Java frame called from C? */
140 public boolean isEntryFrame() { return VM.getVM().getStubRoutines().returnsToCallStub(getPC()); }
141 public boolean isNativeFrame() {
142 if (!VM.getVM().isCore()) {
143 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
144 return (cb != null && cb.isNativeMethod());
145 } else {
146 return false;
147 }
148 }
149
150 public boolean isCompiledFrame() {
151 if (Assert.ASSERTS_ENABLED) {
152 Assert.that(!VM.getVM().isCore(), "noncore builds only");
153 }
154 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
155 return (cb != null && cb.isJavaMethod());
156 }
157
158 public boolean isRuntimeFrame() {
159 if (Assert.ASSERTS_ENABLED) {
160 Assert.that(!VM.getVM().isCore(), "noncore builds only");
161 }
162 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
163 if (cb == null) {
164 return false;
165 }
166 if (cb.isRuntimeStub()) return true;
167 else return false;
168 }
169
193
194 /** performs sanity checks on interpreted frames. */
195 public abstract boolean isInterpretedFrameValid();
196
197 /** tells whether this frame is marked for deoptimization */
198 public boolean shouldBeDeoptimized() { throw new RuntimeException("not yet implemented"); }
199
200 /** tells whether this frame can be deoptimized */
201 public boolean canBeDeoptimized() { throw new RuntimeException("not yet implemented"); }
202
203 /** returns the sending frame */
204 public abstract Frame sender(RegisterMap map, CodeBlob nm);
205
206 /** equivalent to sender(map, null) */
207 public Frame sender(RegisterMap map) { return sender(map, null); }
208
209 /** returns the sender, but skips conversion frames */
210 public Frame realSender(RegisterMap map) {
211 if (!VM.getVM().isCore()) {
212 Frame result = sender(map);
213 while (result.isRuntimeFrame()) {
214 result = result.sender(map);
215 }
216 return result;
217 } else {
218 return sender(map);
219 }
220 }
221
222 /** Platform-dependent query indicating whether this frame has a
223 sender. Should return true if it is possible to call sender() at
224 all on this frame. (This is currently only needed for the
225 debugging system, if a stack trace is attempted for a Java
226 thread which has no Java frames, i.e., the signal thread; we
227 have to know to stop traversal at the bottom frame.) */
228 protected abstract boolean hasSenderPD();
229
230 //--------------------------------------------------------------------------------
231 // All frames:
232 // A low-level interface for vframes:
233
607 // => process callee's arguments
608 //
609 // Note: The expression stack can be empty if an exception
610 // occured during method resolution/execution. In all
611 // cases we empty the expression stack completely be-
612 // fore handling the exception (the exception handling
613 // code in the interpreter calls a blocking runtime
614 // routine which can cause this code to be executed).
615 // (was bug gri 7/27/98)
616 oopsInterpretedArgumentsDo(call.signature(), call.isInvokestatic(), oopVisitor);
617 }
618 }
619 }
620
621 private void oopsEntryDo (AddressVisitor oopVisitor, RegisterMap regMap) {}
622 private void oopsCodeBlobDo (AddressVisitor oopVisitor, RegisterMap regMap) {
623 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
624 if (Assert.ASSERTS_ENABLED) {
625 Assert.that(cb != null, "sanity check");
626 }
627 if (cb.getOopMaps() != null) {
628 OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
629
630 // FIXME: add in traversal of argument oops (skipping this for
631 // now until we have the other stuff tested)
632
633 }
634
635 // FIXME: would add this in in non-debugging system
636
637 // If we see an activation belonging to a non_entrant nmethod, we mark it.
638 // if (cb->is_nmethod() && ((nmethod *)cb)->is_not_entrant()) {
639 // ((nmethod*)cb)->mark_as_seen_on_stack();
640 // }
641 }
642
643 // FIXME: implement the above routines, plus add
644 // oops_interpreted_arguments_do and oops_compiled_arguments_do
645 }
646
647 //
648 // Only used internally, to iterate through oop slots in interpreted
649 // frames
650 //
651 class InterpreterFrameClosure implements OffsetClosure {
652 // Used for debugging this code
653 private static final boolean DEBUG = false;
654
655 private Frame fr;
656 private AddressVisitor f;
657 private int maxLocals;
658 private int maxStack;
659
660 InterpreterFrameClosure(Frame fr, int maxLocals, int maxStack, AddressVisitor f) {
661 this.fr = fr;
662 this.maxLocals = maxLocals;
|