Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/vframe.hpp @ 508:6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
Summary: Replaces SharedRuntime::f2i et al with versions that should work
Reviewed-by: never
Contributed-by: gbenson@redhat.com
author | kvn |
---|---|
date | Mon, 22 Dec 2008 15:43:02 -0800 |
parents | d1605aabd0a1 |
children | b109e761e927 |
rev | line source |
---|---|
0 | 1 /* |
196 | 2 * Copyright 1997-2008 Sun Microsystems, Inc. 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 * | |
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 // vframes are virtual stack frames representing source level activations. | |
26 // A single frame may hold several source level activations in the case of | |
27 // optimized code. The debugging stored with the optimized code enables | |
28 // us to unfold a frame as a stack of vframes. | |
29 // A cVFrame represents an activation of a non-java method. | |
30 | |
31 // The vframe inheritance hierarchy: | |
32 // - vframe | |
33 // - javaVFrame | |
34 // - interpretedVFrame | |
35 // - compiledVFrame ; (used for both compiled Java methods and native stubs) | |
36 // - externalVFrame | |
37 // - entryVFrame ; special frame created when calling Java from C | |
38 | |
39 // - BasicLock | |
40 | |
41 class vframe: public ResourceObj { | |
42 protected: | |
43 frame _fr; // Raw frame behind the virtual frame. | |
44 RegisterMap _reg_map; // Register map for the raw frame (used to handle callee-saved registers). | |
45 JavaThread* _thread; // The thread owning the raw frame. | |
46 | |
47 vframe(const frame* fr, const RegisterMap* reg_map, JavaThread* thread); | |
48 vframe(const frame* fr, JavaThread* thread); | |
49 public: | |
50 // Factory method for creating vframes | |
51 static vframe* new_vframe(const frame* f, const RegisterMap *reg_map, JavaThread* thread); | |
52 | |
53 // Accessors | |
54 frame fr() const { return _fr; } | |
55 CodeBlob* cb() const { return _fr.cb(); } | |
56 nmethod* nm() const { | |
57 assert( cb() != NULL && cb()->is_nmethod(), "usage"); | |
58 return (nmethod*) cb(); | |
59 } | |
60 | |
61 // ???? Does this need to be a copy? | |
62 frame* frame_pointer() { return &_fr; } | |
63 const RegisterMap* register_map() const { return &_reg_map; } | |
64 JavaThread* thread() const { return _thread; } | |
65 | |
66 // Returns the sender vframe | |
67 virtual vframe* sender() const; | |
68 | |
69 // Returns the next javaVFrame on the stack (skipping all other kinds of frame) | |
70 javaVFrame *java_sender() const; | |
71 | |
72 // Answers if the this is the top vframe in the frame, i.e., if the sender vframe | |
73 // is in the caller frame | |
74 virtual bool is_top() const { return true; } | |
75 | |
76 // Returns top vframe within same frame (see is_top()) | |
77 virtual vframe* top() const; | |
78 | |
79 // Type testing operations | |
80 virtual bool is_entry_frame() const { return false; } | |
81 virtual bool is_java_frame() const { return false; } | |
82 virtual bool is_interpreted_frame() const { return false; } | |
83 virtual bool is_compiled_frame() const { return false; } | |
84 | |
85 #ifndef PRODUCT | |
86 // printing operations | |
87 virtual void print_value() const; | |
88 virtual void print(); | |
89 #endif | |
90 }; | |
91 | |
92 | |
93 class javaVFrame: public vframe { | |
94 public: | |
95 // JVM state | |
96 virtual methodOop method() const = 0; | |
97 virtual int bci() const = 0; | |
98 virtual StackValueCollection* locals() const = 0; | |
99 virtual StackValueCollection* expressions() const = 0; | |
100 // the order returned by monitors() is from oldest -> youngest#4418568 | |
101 virtual GrowableArray<MonitorInfo*>* monitors() const = 0; | |
102 | |
103 // Debugging support via JVMTI. | |
104 // NOTE that this is not guaranteed to give correct results for compiled vframes. | |
105 // Deoptimize first if necessary. | |
106 virtual void set_locals(StackValueCollection* values) const = 0; | |
107 | |
108 // Test operation | |
109 bool is_java_frame() const { return true; } | |
110 | |
111 protected: | |
112 javaVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : vframe(fr, reg_map, thread) {} | |
113 javaVFrame(const frame* fr, JavaThread* thread) : vframe(fr, thread) {} | |
114 | |
115 public: | |
116 // casting | |
117 static javaVFrame* cast(vframe* vf) { | |
118 assert(vf == NULL || vf->is_java_frame(), "must be java frame"); | |
119 return (javaVFrame*) vf; | |
120 } | |
121 | |
122 // Return an array of monitors locked by this frame in the youngest to oldest order | |
123 GrowableArray<MonitorInfo*>* locked_monitors(); | |
124 | |
125 // printing used during stack dumps | |
126 void print_lock_info_on(outputStream* st, int frame_count); | |
127 void print_lock_info(int frame_count) { print_lock_info_on(tty, frame_count); } | |
128 | |
129 #ifndef PRODUCT | |
130 public: | |
131 // printing operations | |
132 void print(); | |
133 void print_value() const; | |
134 void print_activation(int index) const; | |
135 | |
136 // verify operations | |
137 virtual void verify() const; | |
138 | |
139 // Structural compare | |
140 bool structural_compare(javaVFrame* other); | |
141 #endif | |
142 friend class vframe; | |
143 }; | |
144 | |
145 class interpretedVFrame: public javaVFrame { | |
146 public: | |
147 // JVM state | |
148 methodOop method() const; | |
149 int bci() const; | |
150 StackValueCollection* locals() const; | |
151 StackValueCollection* expressions() const; | |
152 GrowableArray<MonitorInfo*>* monitors() const; | |
153 | |
154 void set_locals(StackValueCollection* values) const; | |
155 | |
156 // Test operation | |
157 bool is_interpreted_frame() const { return true; } | |
158 | |
159 protected: | |
160 interpretedVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : javaVFrame(fr, reg_map, thread) {}; | |
161 | |
162 public: | |
163 // Accessors for Byte Code Pointer | |
164 u_char* bcp() const; | |
165 void set_bcp(u_char* bcp); | |
166 | |
167 // casting | |
168 static interpretedVFrame* cast(vframe* vf) { | |
169 assert(vf == NULL || vf->is_interpreted_frame(), "must be interpreted frame"); | |
170 return (interpretedVFrame*) vf; | |
171 } | |
172 | |
173 private: | |
174 static const int bcp_offset; | |
175 intptr_t* locals_addr_at(int offset) const; | |
176 | |
177 // returns where the parameters starts relative to the frame pointer | |
178 int start_of_parameters() const; | |
179 | |
180 #ifndef PRODUCT | |
181 public: | |
182 // verify operations | |
183 void verify() const; | |
184 #endif | |
185 friend class vframe; | |
186 }; | |
187 | |
188 | |
189 class externalVFrame: public vframe { | |
190 protected: | |
191 externalVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : vframe(fr, reg_map, thread) {} | |
192 | |
193 #ifndef PRODUCT | |
194 public: | |
195 // printing operations | |
196 void print_value() const; | |
197 void print(); | |
198 #endif | |
199 friend class vframe; | |
200 }; | |
201 | |
202 class entryVFrame: public externalVFrame { | |
203 public: | |
204 bool is_entry_frame() const { return true; } | |
205 | |
206 protected: | |
207 entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread); | |
208 | |
209 public: | |
210 // casting | |
211 static entryVFrame* cast(vframe* vf) { | |
212 assert(vf == NULL || vf->is_entry_frame(), "must be entry frame"); | |
213 return (entryVFrame*) vf; | |
214 } | |
215 | |
216 #ifndef PRODUCT | |
217 public: | |
218 // printing | |
219 void print_value() const; | |
220 void print(); | |
221 #endif | |
222 friend class vframe; | |
223 }; | |
224 | |
225 | |
226 // A MonitorInfo is a ResourceObject that describes a the pair: | |
227 // 1) the owner of the monitor | |
228 // 2) the monitor lock | |
229 class MonitorInfo : public ResourceObj { | |
230 private: | |
231 oop _owner; // the object owning the monitor | |
232 BasicLock* _lock; | |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
0
diff
changeset
|
233 bool _eliminated; |
0 | 234 public: |
235 // Constructor | |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
0
diff
changeset
|
236 MonitorInfo(oop owner, BasicLock* lock, bool eliminated) { |
0 | 237 _owner = owner; |
238 _lock = lock; | |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
0
diff
changeset
|
239 _eliminated = eliminated; |
0 | 240 } |
241 // Accessors | |
242 oop owner() const { return _owner; } | |
243 BasicLock* lock() const { return _lock; } | |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
0
diff
changeset
|
244 bool eliminated() const { return _eliminated; } |
0 | 245 }; |
246 | |
247 class vframeStreamCommon : StackObj { | |
248 protected: | |
249 // common | |
250 frame _frame; | |
251 JavaThread* _thread; | |
252 RegisterMap _reg_map; | |
253 enum { interpreted_mode, compiled_mode, at_end_mode } _mode; | |
254 | |
255 int _sender_decode_offset; | |
256 | |
257 // Cached information | |
258 methodOop _method; | |
259 int _bci; | |
260 | |
261 // Should VM activations be ignored or not | |
262 bool _stop_at_java_call_stub; | |
263 | |
264 bool fill_in_compiled_inlined_sender(); | |
265 void fill_from_compiled_frame(int decode_offset); | |
266 void fill_from_compiled_native_frame(); | |
267 | |
268 void found_bad_method_frame(); | |
269 | |
270 void fill_from_interpreter_frame(); | |
271 bool fill_from_frame(); | |
272 | |
273 // Helper routine for security_get_caller_frame | |
274 void skip_prefixed_method_and_wrappers(); | |
275 | |
276 public: | |
277 // Constructor | |
278 vframeStreamCommon(JavaThread* thread) : _reg_map(thread, false) { | |
279 _thread = thread; | |
280 } | |
281 | |
282 // Accessors | |
283 methodOop method() const { return _method; } | |
284 int bci() const { return _bci; } | |
285 intptr_t* frame_id() const { return _frame.id(); } | |
286 address frame_pc() const { return _frame.pc(); } | |
287 | |
288 CodeBlob* cb() const { return _frame.cb(); } | |
289 nmethod* nm() const { | |
290 assert( cb() != NULL && cb()->is_nmethod(), "usage"); | |
291 return (nmethod*) cb(); | |
292 } | |
293 | |
294 // Frame type | |
295 bool is_interpreted_frame() const { return _frame.is_interpreted_frame(); } | |
296 bool is_entry_frame() const { return _frame.is_entry_frame(); } | |
297 | |
298 // Iteration | |
299 void next() { | |
300 // handle frames with inlining | |
301 if (_mode == compiled_mode && fill_in_compiled_inlined_sender()) return; | |
302 | |
303 // handle general case | |
304 do { | |
305 _frame = _frame.sender(&_reg_map); | |
306 } while (!fill_from_frame()); | |
307 } | |
308 | |
309 bool at_end() const { return _mode == at_end_mode; } | |
310 | |
311 // Implements security traversal. Skips depth no. of frame including | |
312 // special security frames and prefixed native methods | |
313 void security_get_caller_frame(int depth); | |
314 | |
315 // Helper routine for JVM_LatestUserDefinedLoader -- needed for 1.4 | |
316 // reflection implementation | |
317 void skip_reflection_related_frames(); | |
318 }; | |
319 | |
320 class vframeStream : public vframeStreamCommon { | |
321 public: | |
322 // Constructors | |
323 vframeStream(JavaThread* thread, bool stop_at_java_call_stub = false) | |
324 : vframeStreamCommon(thread) { | |
325 _stop_at_java_call_stub = stop_at_java_call_stub; | |
326 | |
327 if (!thread->has_last_Java_frame()) { | |
328 _mode = at_end_mode; | |
329 return; | |
330 } | |
331 | |
332 _frame = _thread->last_frame(); | |
333 while (!fill_from_frame()) { | |
334 _frame = _frame.sender(&_reg_map); | |
335 } | |
336 } | |
337 | |
338 // top_frame may not be at safepoint, start with sender | |
339 vframeStream(JavaThread* thread, frame top_frame, bool stop_at_java_call_stub = false); | |
340 }; | |
341 | |
342 | |
343 inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() { | |
344 if (_sender_decode_offset == DebugInformationRecorder::serialized_null) { | |
345 return false; | |
346 } | |
347 fill_from_compiled_frame(_sender_decode_offset); | |
348 return true; | |
349 } | |
350 | |
351 | |
352 inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) { | |
353 _mode = compiled_mode; | |
354 | |
355 // Range check to detect ridiculous offsets. | |
356 if (decode_offset == DebugInformationRecorder::serialized_null || | |
357 decode_offset < 0 || | |
358 decode_offset >= nm()->scopes_data_size()) { | |
359 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. | |
360 // If we attempt to read nmethod::scopes_data at serialized_null (== 0), | |
361 // or if we read some at other crazy offset, | |
362 // we will decode garbage and make wild references into the heap, | |
363 // leading to crashes in product mode. | |
364 // (This isn't airtight, of course, since there are internal | |
365 // offsets which are also crazy.) | |
366 #ifdef ASSERT | |
367 if (WizardMode) { | |
368 tty->print_cr("Error in fill_from_frame: pc_desc for " | |
369 INTPTR_FORMAT " not found or invalid at %d", | |
370 _frame.pc(), decode_offset); | |
371 nm()->print(); | |
372 nm()->method()->print_codes(); | |
373 nm()->print_code(); | |
374 nm()->print_pcs(); | |
375 } | |
376 #endif | |
377 // Provide a cheap fallback in product mode. (See comment above.) | |
378 found_bad_method_frame(); | |
379 fill_from_compiled_native_frame(); | |
380 return; | |
381 } | |
382 | |
383 // Decode first part of scopeDesc | |
384 DebugInfoReadStream buffer(nm(), decode_offset); | |
385 _sender_decode_offset = buffer.read_int(); | |
386 _method = methodOop(buffer.read_oop()); | |
387 _bci = buffer.read_bci(); | |
388 | |
389 assert(_method->is_method(), "checking type of decoded method"); | |
390 } | |
391 | |
392 // The native frames are handled specially. We do not rely on ScopeDesc info | |
393 // since the pc might not be exact due to the _last_native_pc trick. | |
394 inline void vframeStreamCommon::fill_from_compiled_native_frame() { | |
395 _mode = compiled_mode; | |
396 _sender_decode_offset = DebugInformationRecorder::serialized_null; | |
397 _method = nm()->method(); | |
398 _bci = 0; | |
399 } | |
400 | |
401 inline bool vframeStreamCommon::fill_from_frame() { | |
402 // Interpreted frame | |
403 if (_frame.is_interpreted_frame()) { | |
404 fill_from_interpreter_frame(); | |
405 return true; | |
406 } | |
407 | |
408 // Compiled frame | |
409 | |
410 if (cb() != NULL && cb()->is_nmethod()) { | |
411 if (nm()->is_native_method()) { | |
412 // Do not rely on scopeDesc since the pc might be unprecise due to the _last_native_pc trick. | |
413 fill_from_compiled_native_frame(); | |
414 } else { | |
415 PcDesc* pc_desc = nm()->pc_desc_at(_frame.pc()); | |
416 int decode_offset; | |
417 if (pc_desc == NULL) { | |
418 // Should not happen, but let fill_from_compiled_frame handle it. | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
419 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
420 // If we are trying to walk the stack of a thread that is not |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
421 // at a safepoint (like AsyncGetCallTrace would do) then this is an |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
422 // acceptable result. [ This is assuming that safe_for_sender |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
423 // is so bullet proof that we can trust the frames it produced. ] |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
424 // |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
425 // So if we see that the thread is not safepoint safe |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
426 // then simply produce the method and a bci of zero |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
427 // and skip the possibility of decoding any inlining that |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
428 // may be present. That is far better than simply stopping (or |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
429 // asserting. If however the thread is safepoint safe this |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
430 // is the sign of a compiler bug and we'll let |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
431 // fill_from_compiled_frame handle it. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
432 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
433 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
434 JavaThreadState state = _thread->thread_state(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
435 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
436 // in_Java should be good enough to test safepoint safety |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
437 // if state were say in_Java_trans then we'd expect that |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
438 // the pc would have already been slightly adjusted to |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
439 // one that would produce a pcDesc since the trans state |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
440 // would be one that might in fact anticipate a safepoint |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
441 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
442 if (state == _thread_in_Java ) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
443 // This will get a method a zero bci and no inlining. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
444 // Might be nice to have a unique bci to signify this |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
445 // particular case but for now zero will do. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
446 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
447 fill_from_compiled_native_frame(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
448 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
449 // There is something to be said for setting the mode to |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
450 // at_end_mode to prevent trying to walk further up the |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
451 // stack. There is evidence that if we walk any further |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
452 // that we could produce a bad stack chain. However until |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
453 // we see evidence that allowing this causes us to find |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
454 // frames bad enough to cause segv's or assertion failures |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
455 // we don't do it as while we may get a bad call chain the |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
456 // probability is much higher (several magnitudes) that we |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
457 // get good data. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
458 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
459 return true; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
460 } |
0 | 461 decode_offset = DebugInformationRecorder::serialized_null; |
462 } else { | |
463 decode_offset = pc_desc->scope_decode_offset(); | |
464 } | |
465 fill_from_compiled_frame(decode_offset); | |
466 } | |
467 return true; | |
468 } | |
469 | |
470 // End of stack? | |
471 if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) { | |
472 _mode = at_end_mode; | |
473 return true; | |
474 } | |
475 | |
476 return false; | |
477 } | |
478 | |
479 | |
480 inline void vframeStreamCommon::fill_from_interpreter_frame() { | |
481 methodOop method = _frame.interpreter_frame_method(); | |
482 intptr_t bcx = _frame.interpreter_frame_bcx(); | |
483 int bci = method->validate_bci_from_bcx(bcx); | |
484 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. | |
485 if (bci < 0) { | |
486 found_bad_method_frame(); | |
487 bci = 0; // pretend it's on the point of entering | |
488 } | |
489 _mode = interpreted_mode; | |
490 _method = method; | |
491 _bci = bci; | |
492 } |