Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/vframe.hpp @ 452:00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery.
Reviewed-by: apetrusenko, jcoomes
author | ysr |
---|---|
date | Thu, 20 Nov 2008 12:27:41 -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 } |