31 import sun.jvm.hotspot.compiler.*; |
31 import sun.jvm.hotspot.compiler.*; |
32 import sun.jvm.hotspot.c1.*; |
32 import sun.jvm.hotspot.c1.*; |
33 import sun.jvm.hotspot.debugger.*; |
33 import sun.jvm.hotspot.debugger.*; |
34 import sun.jvm.hotspot.interpreter.*; |
34 import sun.jvm.hotspot.interpreter.*; |
35 import sun.jvm.hotspot.oops.*; |
35 import sun.jvm.hotspot.oops.*; |
|
36 import sun.jvm.hotspot.runtime.sparc.SPARCFrame; |
36 import sun.jvm.hotspot.types.*; |
37 import sun.jvm.hotspot.types.*; |
37 import sun.jvm.hotspot.utilities.*; |
38 import sun.jvm.hotspot.utilities.*; |
38 |
39 |
39 /** <P> A frame represents a physical stack frame (an activation). |
40 /** <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 Frames can be C or Java frames, and the Java frames can be |
72 } |
73 } |
73 |
74 |
74 /** Size of constMethodOopDesc for computing BCI from BCP (FIXME: hack) */ |
75 /** Size of constMethodOopDesc for computing BCI from BCP (FIXME: hack) */ |
75 private static long constMethodOopDescSize; |
76 private static long constMethodOopDescSize; |
76 |
77 |
|
78 private static int pcReturnOffset; |
|
79 |
|
80 public static int pcReturnOffset() { |
|
81 return pcReturnOffset; |
|
82 } |
|
83 |
77 private static synchronized void initialize(TypeDataBase db) { |
84 private static synchronized void initialize(TypeDataBase db) { |
78 Type constMethodOopType = db.lookupType("constMethodOopDesc"); |
85 Type constMethodOopType = db.lookupType("constMethodOopDesc"); |
79 // FIXME: not sure whether alignment here is correct or how to |
86 // FIXME: not sure whether alignment here is correct or how to |
80 // force it (round up to address size?) |
87 // force it (round up to address size?) |
81 constMethodOopDescSize = constMethodOopType.getSize(); |
88 constMethodOopDescSize = constMethodOopType.getSize(); |
|
89 |
|
90 pcReturnOffset = db.lookupIntConstant("frame::pc_return_offset").intValue(); |
82 } |
91 } |
83 |
92 |
84 protected int bcpToBci(Address bcp, ConstMethod cm) { |
93 protected int bcpToBci(Address bcp, ConstMethod cm) { |
85 // bcp will be null for interpreter native methods |
94 // bcp will be null for interpreter native methods |
86 // in addition depending on where we catch the system the value can |
95 // in addition depending on where we catch the system the value can |
104 execute. */ |
113 execute. */ |
105 public Address getPC() { return pc; } |
114 public Address getPC() { return pc; } |
106 public void setPC(Address newpc) { pc = newpc; } |
115 public void setPC(Address newpc) { pc = newpc; } |
107 public boolean isDeoptimized() { return deoptimized; } |
116 public boolean isDeoptimized() { return deoptimized; } |
108 |
117 |
|
118 public CodeBlob cb() { |
|
119 return VM.getVM().getCodeCache().findBlob(getPC()); |
|
120 } |
|
121 |
109 public abstract Address getSP(); |
122 public abstract Address getSP(); |
110 public abstract Address getID(); |
123 public abstract Address getID(); |
111 public abstract Address getFP(); |
124 public abstract Address getFP(); |
112 |
125 |
113 /** testers -- platform dependent */ |
126 /** testers -- platform dependent */ |
132 } else { |
145 } else { |
133 return false; |
146 return false; |
134 } |
147 } |
135 } |
148 } |
136 |
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 |
137 public boolean isCompiledFrame() { |
156 public boolean isCompiledFrame() { |
138 if (Assert.ASSERTS_ENABLED) { |
157 if (Assert.ASSERTS_ENABLED) { |
139 Assert.that(!VM.getVM().isCore(), "noncore builds only"); |
158 Assert.that(!VM.getVM().isCore(), "noncore builds only"); |
140 } |
159 } |
141 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); |
160 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); |
142 return (cb != null && cb.isJavaMethod()); |
161 return (cb != null && cb.isJavaMethod()); |
143 } |
162 } |
144 |
163 |
145 public boolean isGlueFrame() { |
164 public boolean isRuntimeFrame() { |
146 if (Assert.ASSERTS_ENABLED) { |
165 if (Assert.ASSERTS_ENABLED) { |
147 Assert.that(!VM.getVM().isCore(), "noncore builds only"); |
166 Assert.that(!VM.getVM().isCore(), "noncore builds only"); |
148 } |
167 } |
149 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); |
168 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); |
150 if (cb == null) { |
169 if (cb == null) { |
195 |
214 |
196 /** returns the sender, but skips conversion frames */ |
215 /** returns the sender, but skips conversion frames */ |
197 public Frame realSender(RegisterMap map) { |
216 public Frame realSender(RegisterMap map) { |
198 if (!VM.getVM().isCore()) { |
217 if (!VM.getVM().isCore()) { |
199 Frame result = sender(map); |
218 Frame result = sender(map); |
200 while (result.isGlueFrame()) { |
219 while (result.isRuntimeFrame() || |
|
220 result.isRicochetFrame()) { |
201 result = result.sender(map); |
221 result = result.sender(map); |
202 } |
222 } |
203 return result; |
223 return result; |
204 } else { |
224 } else { |
205 return sender(map); |
225 return sender(map); |
609 private void oopsCodeBlobDo (AddressVisitor oopVisitor, RegisterMap regMap) { |
629 private void oopsCodeBlobDo (AddressVisitor oopVisitor, RegisterMap regMap) { |
610 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); |
630 CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC()); |
611 if (Assert.ASSERTS_ENABLED) { |
631 if (Assert.ASSERTS_ENABLED) { |
612 Assert.that(cb != null, "sanity check"); |
632 Assert.that(cb != null, "sanity check"); |
613 } |
633 } |
|
634 if (cb == VM.getVM().ricochetBlob()) { |
|
635 oopsRicochetDo(oopVisitor, regMap); |
|
636 } |
614 if (cb.getOopMaps() != null) { |
637 if (cb.getOopMaps() != null) { |
615 OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging()); |
638 OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging()); |
616 |
639 |
617 // FIXME: add in traversal of argument oops (skipping this for |
640 // FIXME: add in traversal of argument oops (skipping this for |
618 // now until we have the other stuff tested) |
641 // now until we have the other stuff tested) |
623 |
646 |
624 // If we see an activation belonging to a non_entrant nmethod, we mark it. |
647 // If we see an activation belonging to a non_entrant nmethod, we mark it. |
625 // if (cb->is_nmethod() && ((nmethod *)cb)->is_not_entrant()) { |
648 // if (cb->is_nmethod() && ((nmethod *)cb)->is_not_entrant()) { |
626 // ((nmethod*)cb)->mark_as_seen_on_stack(); |
649 // ((nmethod*)cb)->mark_as_seen_on_stack(); |
627 // } |
650 // } |
|
651 } |
|
652 |
|
653 private void oopsRicochetDo (AddressVisitor oopVisitor, RegisterMap regMap) { |
|
654 // XXX Empty for now |
628 } |
655 } |
629 |
656 |
630 // FIXME: implement the above routines, plus add |
657 // FIXME: implement the above routines, plus add |
631 // oops_interpreted_arguments_do and oops_compiled_arguments_do |
658 // oops_interpreted_arguments_do and oops_compiled_arguments_do |
632 } |
659 } |