Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/vframe.hpp @ 1039:987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
Summary: correctly raise exceptions, support safe bitwise "raw" conversions, fix bugs revealed by VerifyMethodHandles, remove dead code, improve debugging support
Reviewed-by: never, twisti
author | jrose |
---|---|
date | Sat, 17 Oct 2009 19:51:05 -0700 |
parents | 72088be4b386 |
children | c18cbe5936b8 |
rev | line source |
---|---|
0 | 1 /* |
844 | 2 * Copyright 1997-2009 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; | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
233 oop _owner_klass; // klass if owner was scalar replaced |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
0
diff
changeset
|
234 bool _eliminated; |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
235 bool _owner_is_scalar_replaced; |
0 | 236 public: |
237 // Constructor | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
238 MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced) { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
239 if (!owner_is_scalar_replaced) { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
240 _owner = owner; |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
241 _owner_klass = NULL; |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
242 } else { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
243 assert(eliminated, "monitor should be eliminated for scalar replaced object"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
244 _owner = NULL; |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
245 _owner_klass = owner; |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
246 } |
0 | 247 _lock = lock; |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
0
diff
changeset
|
248 _eliminated = eliminated; |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
249 _owner_is_scalar_replaced = owner_is_scalar_replaced; |
0 | 250 } |
251 // Accessors | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
252 oop owner() const { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
253 assert(!_owner_is_scalar_replaced, "should not be called for scalar replaced object"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
254 return _owner; |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
255 } |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
256 klassOop owner_klass() const { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
257 assert(_owner_is_scalar_replaced, "should not be called for not scalar replaced object"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
258 return (klassOop)_owner_klass; |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
259 } |
0 | 260 BasicLock* lock() const { return _lock; } |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
0
diff
changeset
|
261 bool eliminated() const { return _eliminated; } |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
262 bool owner_is_scalar_replaced() const { return _owner_is_scalar_replaced; } |
0 | 263 }; |
264 | |
265 class vframeStreamCommon : StackObj { | |
266 protected: | |
267 // common | |
268 frame _frame; | |
269 JavaThread* _thread; | |
270 RegisterMap _reg_map; | |
271 enum { interpreted_mode, compiled_mode, at_end_mode } _mode; | |
272 | |
273 int _sender_decode_offset; | |
274 | |
275 // Cached information | |
276 methodOop _method; | |
277 int _bci; | |
278 | |
279 // Should VM activations be ignored or not | |
280 bool _stop_at_java_call_stub; | |
281 | |
282 bool fill_in_compiled_inlined_sender(); | |
283 void fill_from_compiled_frame(int decode_offset); | |
284 void fill_from_compiled_native_frame(); | |
285 | |
286 void found_bad_method_frame(); | |
287 | |
288 void fill_from_interpreter_frame(); | |
289 bool fill_from_frame(); | |
290 | |
291 // Helper routine for security_get_caller_frame | |
292 void skip_prefixed_method_and_wrappers(); | |
293 | |
294 public: | |
295 // Constructor | |
296 vframeStreamCommon(JavaThread* thread) : _reg_map(thread, false) { | |
297 _thread = thread; | |
298 } | |
299 | |
300 // Accessors | |
301 methodOop method() const { return _method; } | |
302 int bci() const { return _bci; } | |
303 intptr_t* frame_id() const { return _frame.id(); } | |
304 address frame_pc() const { return _frame.pc(); } | |
305 | |
306 CodeBlob* cb() const { return _frame.cb(); } | |
307 nmethod* nm() const { | |
308 assert( cb() != NULL && cb()->is_nmethod(), "usage"); | |
309 return (nmethod*) cb(); | |
310 } | |
311 | |
312 // Frame type | |
313 bool is_interpreted_frame() const { return _frame.is_interpreted_frame(); } | |
314 bool is_entry_frame() const { return _frame.is_entry_frame(); } | |
315 | |
316 // Iteration | |
317 void next() { | |
318 // handle frames with inlining | |
319 if (_mode == compiled_mode && fill_in_compiled_inlined_sender()) return; | |
320 | |
321 // handle general case | |
322 do { | |
323 _frame = _frame.sender(&_reg_map); | |
324 } while (!fill_from_frame()); | |
325 } | |
326 | |
327 bool at_end() const { return _mode == at_end_mode; } | |
328 | |
329 // Implements security traversal. Skips depth no. of frame including | |
330 // special security frames and prefixed native methods | |
331 void security_get_caller_frame(int depth); | |
332 | |
333 // Helper routine for JVM_LatestUserDefinedLoader -- needed for 1.4 | |
334 // reflection implementation | |
335 void skip_reflection_related_frames(); | |
336 }; | |
337 | |
338 class vframeStream : public vframeStreamCommon { | |
339 public: | |
340 // Constructors | |
341 vframeStream(JavaThread* thread, bool stop_at_java_call_stub = false) | |
342 : vframeStreamCommon(thread) { | |
343 _stop_at_java_call_stub = stop_at_java_call_stub; | |
344 | |
345 if (!thread->has_last_Java_frame()) { | |
346 _mode = at_end_mode; | |
347 return; | |
348 } | |
349 | |
350 _frame = _thread->last_frame(); | |
351 while (!fill_from_frame()) { | |
352 _frame = _frame.sender(&_reg_map); | |
353 } | |
354 } | |
355 | |
356 // top_frame may not be at safepoint, start with sender | |
357 vframeStream(JavaThread* thread, frame top_frame, bool stop_at_java_call_stub = false); | |
358 }; | |
359 | |
360 | |
361 inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() { | |
362 if (_sender_decode_offset == DebugInformationRecorder::serialized_null) { | |
363 return false; | |
364 } | |
365 fill_from_compiled_frame(_sender_decode_offset); | |
366 return true; | |
367 } | |
368 | |
369 | |
370 inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) { | |
371 _mode = compiled_mode; | |
372 | |
373 // Range check to detect ridiculous offsets. | |
374 if (decode_offset == DebugInformationRecorder::serialized_null || | |
375 decode_offset < 0 || | |
376 decode_offset >= nm()->scopes_data_size()) { | |
377 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. | |
378 // If we attempt to read nmethod::scopes_data at serialized_null (== 0), | |
379 // or if we read some at other crazy offset, | |
380 // we will decode garbage and make wild references into the heap, | |
381 // leading to crashes in product mode. | |
382 // (This isn't airtight, of course, since there are internal | |
383 // offsets which are also crazy.) | |
384 #ifdef ASSERT | |
385 if (WizardMode) { | |
386 tty->print_cr("Error in fill_from_frame: pc_desc for " | |
387 INTPTR_FORMAT " not found or invalid at %d", | |
388 _frame.pc(), decode_offset); | |
389 nm()->print(); | |
390 nm()->method()->print_codes(); | |
391 nm()->print_code(); | |
392 nm()->print_pcs(); | |
393 } | |
394 #endif | |
395 // Provide a cheap fallback in product mode. (See comment above.) | |
396 found_bad_method_frame(); | |
397 fill_from_compiled_native_frame(); | |
398 return; | |
399 } | |
400 | |
401 // Decode first part of scopeDesc | |
402 DebugInfoReadStream buffer(nm(), decode_offset); | |
403 _sender_decode_offset = buffer.read_int(); | |
404 _method = methodOop(buffer.read_oop()); | |
931
72088be4b386
6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents:
903
diff
changeset
|
405 _bci = buffer.read_bci(); |
0 | 406 |
407 assert(_method->is_method(), "checking type of decoded method"); | |
408 } | |
409 | |
410 // The native frames are handled specially. We do not rely on ScopeDesc info | |
411 // since the pc might not be exact due to the _last_native_pc trick. | |
412 inline void vframeStreamCommon::fill_from_compiled_native_frame() { | |
413 _mode = compiled_mode; | |
414 _sender_decode_offset = DebugInformationRecorder::serialized_null; | |
415 _method = nm()->method(); | |
416 _bci = 0; | |
417 } | |
418 | |
419 inline bool vframeStreamCommon::fill_from_frame() { | |
420 // Interpreted frame | |
421 if (_frame.is_interpreted_frame()) { | |
422 fill_from_interpreter_frame(); | |
423 return true; | |
424 } | |
425 | |
426 // Compiled frame | |
427 | |
428 if (cb() != NULL && cb()->is_nmethod()) { | |
429 if (nm()->is_native_method()) { | |
430 // Do not rely on scopeDesc since the pc might be unprecise due to the _last_native_pc trick. | |
431 fill_from_compiled_native_frame(); | |
432 } else { | |
433 PcDesc* pc_desc = nm()->pc_desc_at(_frame.pc()); | |
434 int decode_offset; | |
435 if (pc_desc == NULL) { | |
436 // 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
|
437 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
438 // 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
|
439 // 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
|
440 // 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
|
441 // 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
|
442 // |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
443 // 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
|
444 // 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
|
445 // 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
|
446 // 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
|
447 // 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
|
448 // 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
|
449 // 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
|
450 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
451 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
452 JavaThreadState state = _thread->thread_state(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
453 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
454 // 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
|
455 // 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
|
456 // 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
|
457 // 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
|
458 // 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
|
459 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
460 if (state == _thread_in_Java ) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
461 // 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
|
462 // 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
|
463 // 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
|
464 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
465 fill_from_compiled_native_frame(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
466 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
467 // 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
|
468 // 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
|
469 // 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
|
470 // 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
|
471 // 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
|
472 // 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
|
473 // 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
|
474 // 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
|
475 // get good data. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
476 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
477 return true; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
83
diff
changeset
|
478 } |
0 | 479 decode_offset = DebugInformationRecorder::serialized_null; |
480 } else { | |
481 decode_offset = pc_desc->scope_decode_offset(); | |
482 } | |
483 fill_from_compiled_frame(decode_offset); | |
484 } | |
485 return true; | |
486 } | |
487 | |
488 // End of stack? | |
489 if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) { | |
490 _mode = at_end_mode; | |
491 return true; | |
492 } | |
493 | |
494 return false; | |
495 } | |
496 | |
497 | |
498 inline void vframeStreamCommon::fill_from_interpreter_frame() { | |
499 methodOop method = _frame.interpreter_frame_method(); | |
500 intptr_t bcx = _frame.interpreter_frame_bcx(); | |
501 int bci = method->validate_bci_from_bcx(bcx); | |
502 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. | |
503 if (bci < 0) { | |
504 found_bad_method_frame(); | |
505 bci = 0; // pretend it's on the point of entering | |
506 } | |
507 _mode = interpreted_mode; | |
508 _method = method; | |
509 _bci = bci; | |
510 } |