Mercurial > hg > truffle
comparison src/share/vm/prims/forte.cpp @ 1349:547cbe6dacc5
6936709: AsyncGetCallTrace doesn't handle inexact stack walking properly
Reviewed-by: kvn
author | never |
---|---|
date | Thu, 01 Apr 2010 16:06:57 -0700 |
parents | d1605aabd0a1 |
children | cff162798819 |
comparison
equal
deleted
inserted
replaced
1348:7f4deda46b04 | 1349:547cbe6dacc5 |
---|---|
53 vframeStreamForte(JavaThread *jt, frame fr, bool stop_at_java_call_stub); | 53 vframeStreamForte(JavaThread *jt, frame fr, bool stop_at_java_call_stub); |
54 void forte_next(); | 54 void forte_next(); |
55 }; | 55 }; |
56 | 56 |
57 | 57 |
58 static void is_decipherable_compiled_frame(frame* fr, RegisterMap* map, | 58 static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm); |
59 bool* is_compiled_p, bool* is_walkable_p); | |
60 static bool is_decipherable_interpreted_frame(JavaThread* thread, | 59 static bool is_decipherable_interpreted_frame(JavaThread* thread, |
61 frame* fr, | 60 frame* fr, |
62 methodOop* method_p, | 61 methodOop* method_p, |
63 int* bci_p); | 62 int* bci_p); |
64 | 63 |
65 | 64 |
66 | 65 |
67 | 66 |
68 vframeStreamForte::vframeStreamForte(JavaThread *jt, | 67 vframeStreamForte::vframeStreamForte(JavaThread *jt, |
120 } | 119 } |
121 | 120 |
122 // Determine if 'fr' is a decipherable compiled frame. We are already | 121 // Determine if 'fr' is a decipherable compiled frame. We are already |
123 // assured that fr is for a java nmethod. | 122 // assured that fr is for a java nmethod. |
124 | 123 |
125 static bool is_decipherable_compiled_frame(frame* fr) { | 124 static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm) { |
126 | |
127 assert(fr->cb() != NULL && fr->cb()->is_nmethod(), "invariant"); | |
128 nmethod* nm = (nmethod*) fr->cb(); | |
129 assert(nm->is_java_method(), "invariant"); | 125 assert(nm->is_java_method(), "invariant"); |
130 | 126 |
131 // First try and find an exact PcDesc | 127 if (thread->has_last_Java_frame() && thread->last_Java_pc() == fr->pc()) { |
132 | 128 // We're stopped at a call into the JVM so look for a PcDesc with |
133 PcDesc* pc_desc = nm->pc_desc_at(fr->pc()); | 129 // the actual pc reported by the frame. |
134 | 130 PcDesc* pc_desc = nm->pc_desc_at(fr->pc()); |
135 // Did we find a useful PcDesc? | 131 |
136 if (pc_desc != NULL && | 132 // Did we find a useful PcDesc? |
133 if (pc_desc != NULL && | |
134 pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) { | |
135 return true; | |
136 } | |
137 } | |
138 | |
139 // We're at some random pc in the nmethod so search for the PcDesc | |
140 // whose pc is greater than the current PC. It's done this way | |
141 // because the extra PcDescs that are recorded for improved debug | |
142 // info record the end of the region covered by the ScopeDesc | |
143 // instead of the beginning. | |
144 PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1); | |
145 | |
146 // Now do we have a useful PcDesc? | |
147 if (pc_desc == NULL || | |
137 pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) { | 148 pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) { |
138 | 149 // No debug information available for this pc |
139 address probe_pc = fr->pc() + 1; | 150 // vframeStream would explode if we try and walk the frames. |
140 pc_desc = nm->pc_desc_near(probe_pc); | 151 return false; |
141 | 152 } |
142 // Now do we have a useful PcDesc? | 153 |
143 | 154 // This PcDesc is useful however we must adjust the frame's pc |
144 if (pc_desc != NULL && | 155 // so that the vframeStream lookups will use this same pc |
145 pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) { | 156 fr->set_pc(pc_desc->real_pc(nm)); |
146 // No debug information available for this pc | |
147 // vframeStream would explode if we try and walk the frames. | |
148 return false; | |
149 } | |
150 | |
151 // This PcDesc is useful however we must adjust the frame's pc | |
152 // so that the vframeStream lookups will use this same pc | |
153 | |
154 fr->set_pc(pc_desc->real_pc(nm)); | |
155 } | |
156 | |
157 return true; | 157 return true; |
158 } | 158 } |
159 | |
159 | 160 |
160 // Determine if 'fr' is a walkable interpreted frame. Returns false | 161 // Determine if 'fr' is a walkable interpreted frame. Returns false |
161 // if it is not. *method_p, and *bci_p are not set when false is | 162 // if it is not. *method_p, and *bci_p are not set when false is |
162 // returned. *method_p is non-NULL if frame was executing a Java | 163 // returned. *method_p is non-NULL if frame was executing a Java |
163 // method. *bci_p is != -1 if a valid BCI in the Java method could | 164 // method. *bci_p is != -1 if a valid BCI in the Java method could |
164 // be found. | 165 // be found. |
165 // Note: this method returns true when a valid Java method is found | 166 // Note: this method returns true when a valid Java method is found |
166 // even if a valid BCI cannot be found. | 167 // even if a valid BCI cannot be found. |
167 | 168 |
168 static bool is_decipherable_interpreted_frame(JavaThread* thread, | 169 static bool is_decipherable_interpreted_frame(JavaThread* thread, |
169 frame* fr, | 170 frame* fr, |
170 methodOop* method_p, | 171 methodOop* method_p, |
171 int* bci_p) { | 172 int* bci_p) { |
172 assert(fr->is_interpreted_frame(), "just checking"); | 173 assert(fr->is_interpreted_frame(), "just checking"); |
173 | 174 |
174 // top frame is an interpreted frame | 175 // top frame is an interpreted frame |
175 // check if it is walkable (i.e. valid methodOop and valid bci) | 176 // check if it is walkable (i.e. valid methodOop and valid bci) |
176 | 177 |
321 | 322 |
322 // If it isn't decipherable then we have found a pc that doesn't | 323 // If it isn't decipherable then we have found a pc that doesn't |
323 // have a PCDesc that can get us a bci however we did find | 324 // have a PCDesc that can get us a bci however we did find |
324 // a method | 325 // a method |
325 | 326 |
326 if (!is_decipherable_compiled_frame(&candidate)) { | 327 if (!is_decipherable_compiled_frame(thread, &candidate, nm)) { |
327 return false; | 328 return false; |
328 } | 329 } |
329 | 330 |
330 // is_decipherable_compiled_frame may modify candidate's pc | 331 // is_decipherable_compiled_frame may modify candidate's pc |
331 *initial_frame_p = candidate; | 332 *initial_frame_p = candidate; |
333 | |
334 assert(nm->pc_desc_at(candidate.pc()) != NULL, "if it's decipherable then pc must be valid"); | |
332 | 335 |
333 return true; | 336 return true; |
334 } | 337 } |
335 | 338 |
336 // Must be some stub frame that we don't care about | 339 // Must be some stub frame that we don't care about |