24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" |
26 #include "classfile/javaClasses.hpp" |
27 #include "classfile/javaClasses.inline.hpp" |
27 #include "classfile/javaClasses.inline.hpp" |
28 #include "classfile/vmSymbols.hpp" |
28 #include "classfile/vmSymbols.hpp" |
|
29 #include "logging/log.hpp" |
29 #include "memory/oopFactory.hpp" |
30 #include "memory/oopFactory.hpp" |
30 #include "oops/oop.inline.hpp" |
31 #include "oops/oop.inline.hpp" |
31 #include "oops/objArrayOop.inline.hpp" |
32 #include "oops/objArrayOop.inline.hpp" |
32 #include "prims/stackwalk.hpp" |
33 #include "prims/stackwalk.hpp" |
33 #include "runtime/globals.hpp" |
34 #include "runtime/globals.hpp" |
103 // |
104 // |
104 int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream, |
105 int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream, |
105 int max_nframes, int start_index, |
106 int max_nframes, int start_index, |
106 objArrayHandle frames_array, |
107 objArrayHandle frames_array, |
107 int& end_index, TRAPS) { |
108 int& end_index, TRAPS) { |
108 if (TraceStackWalk) { |
109 log_debug(stackwalk)("fill_in_frames limit=%d start=%d frames length=%d", |
109 tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d", |
110 max_nframes, start_index, frames_array->length()); |
110 max_nframes, start_index, frames_array->length()); |
|
111 } |
|
112 assert(max_nframes > 0, "invalid max_nframes"); |
111 assert(max_nframes > 0, "invalid max_nframes"); |
113 assert(start_index + max_nframes <= frames_array->length(), "oob"); |
112 assert(start_index + max_nframes <= frames_array->length(), "oob"); |
114 |
113 |
115 int frames_decoded = 0; |
114 int frames_decoded = 0; |
116 for (; !stream.at_end(); stream.next()) { |
115 for (; !stream.at_end(); stream.next()) { |
120 |
119 |
121 // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES |
120 // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES |
122 // not set) and when StackWalker::getCallerClass is called |
121 // not set) and when StackWalker::getCallerClass is called |
123 if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) { |
122 if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) { |
124 if (method->is_hidden()) { |
123 if (method->is_hidden()) { |
125 if (TraceStackWalk) { |
124 if (log_is_enabled(Debug, stackwalk)) { |
126 tty->print(" hidden method: "); method->print_short_name(); |
125 ResourceMark rm(THREAD); |
127 tty->print("\n"); |
126 outputStream* st = Log(stackwalk)::debug_stream(); |
|
127 st->print(" hidden method: "); |
|
128 method->print_short_name(st); |
|
129 st->cr(); |
128 } |
130 } |
129 continue; |
131 continue; |
130 } |
132 } |
131 } |
133 } |
132 |
134 |
133 int index = end_index++; |
135 int index = end_index++; |
134 if (TraceStackWalk) { |
136 if (log_is_enabled(Debug, stackwalk)) { |
135 tty->print(" %d: frame method: ", index); method->print_short_name(); |
137 ResourceMark rm(THREAD); |
136 tty->print_cr(" bci=%d", stream.bci()); |
138 outputStream* st = Log(stackwalk)::debug_stream(); |
|
139 st->print(" %d: frame method: ", index); |
|
140 method->print_short_name(st); |
|
141 st->print_cr(" bci=%d", stream.bci()); |
137 } |
142 } |
138 |
143 |
139 if (!need_method_info(mode) && get_caller_class(mode) && |
144 if (!need_method_info(mode) && get_caller_class(mode) && |
140 index == start_index && method->caller_sensitive()) { |
145 index == start_index && method->caller_sensitive()) { |
141 ResourceMark rm(THREAD); |
146 ResourceMark rm(THREAD); |
315 int skip_frames, int frame_count, int start_index, |
320 int skip_frames, int frame_count, int start_index, |
316 objArrayHandle frames_array, |
321 objArrayHandle frames_array, |
317 TRAPS) { |
322 TRAPS) { |
318 ResourceMark rm(THREAD); |
323 ResourceMark rm(THREAD); |
319 JavaThread* jt = (JavaThread*)THREAD; |
324 JavaThread* jt = (JavaThread*)THREAD; |
320 if (TraceStackWalk) { |
325 log_debug(stackwalk)("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d", |
321 tty->print_cr("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d", |
326 mode, skip_frames, frame_count); |
322 mode, skip_frames, frame_count); |
|
323 } |
|
324 |
327 |
325 if (frames_array.is_null()) { |
328 if (frames_array.is_null()) { |
326 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL); |
329 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL); |
327 } |
330 } |
328 |
331 |
353 if (ik != stackWalker_klass && |
356 if (ik != stackWalker_klass && |
354 ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) { |
357 ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) { |
355 break; |
358 break; |
356 } |
359 } |
357 |
360 |
358 if (TraceStackWalk) { |
361 if (log_is_enabled(Debug, stackwalk)) { |
359 tty->print(" skip "); stream.method()->print_short_name(); tty->print("\n"); |
362 ResourceMark rm(THREAD); |
|
363 outputStream* st = Log(stackwalk)::debug_stream(); |
|
364 st->print(" skip "); |
|
365 stream.method()->print_short_name(st); |
|
366 st->cr(); |
360 } |
367 } |
361 stream.next(); |
368 stream.next(); |
362 } |
369 } |
363 |
370 |
364 // stack frame has been traversed individually and resume stack walk |
371 // stack frame has been traversed individually and resume stack walk |
365 // from the stack frame at depth == skip_frames. |
372 // from the stack frame at depth == skip_frames. |
366 for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) { |
373 for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) { |
367 if (TraceStackWalk) { |
374 if (log_is_enabled(Debug, stackwalk)) { |
368 tty->print(" skip "); stream.method()->print_short_name(); tty->cr(); |
375 ResourceMark rm(THREAD); |
|
376 outputStream* st = Log(stackwalk)::debug_stream(); |
|
377 st->print(" skip "); |
|
378 stream.method()->print_short_name(st); |
|
379 st->cr(); |
369 } |
380 } |
370 } |
381 } |
371 } |
382 } |
372 |
383 |
373 int end_index = start_index; |
384 int end_index = start_index; |
436 |
447 |
437 if (frames_array.is_null()) { |
448 if (frames_array.is_null()) { |
438 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L); |
449 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L); |
439 } |
450 } |
440 |
451 |
441 if (TraceStackWalk) { |
452 log_debug(stackwalk)("StackWalk::fetchNextBatch frame_count %d existing_stream " |
442 tty->print_cr("StackWalk::fetchNextBatch frame_count %d existing_stream " PTR_FORMAT " start %d frames %d", |
453 PTR_FORMAT " start %d frames %d", |
443 frame_count, p2i(existing_stream), start_index, frames_array->length()); |
454 frame_count, p2i(existing_stream), start_index, frames_array->length()); |
444 } |
|
445 int end_index = start_index; |
455 int end_index = start_index; |
446 if (frame_count <= 0) { |
456 if (frame_count <= 0) { |
447 return end_index; // No operation. |
457 return end_index; // No operation. |
448 } |
458 } |
449 |
459 |