< prev index next >

src/hotspot/share/prims/stackwalk.cpp

Print this page

        

*** 39,48 **** --- 39,53 ---- #include "runtime/thread.inline.hpp" #include "runtime/vframe.inline.hpp" #include "utilities/globalDefinitions.hpp" // setup and cleanup actions + BaseFrameStream::BaseFrameStream(JavaThread* thread, Handle continuation) + : _thread(thread), _continuation(continuation), _anchor(0L) { + assert (thread != NULL, ""); + } + void BaseFrameStream::setup_magic_on_entry(objArrayHandle frames_array) { frames_array->obj_at_put(magic_pos, _thread->threadObj()); _anchor = address_value(); assert(check_magic(frames_array), "invalid magic"); }
*** 59,74 **** frames_array->obj_at_put(magic_pos, NULL); _anchor = 0L; return ok; } ! JavaFrameStream::JavaFrameStream(JavaThread* thread, int mode) ! : BaseFrameStream(thread), _vfst(thread) { _need_method_info = StackWalk::need_method_info(mode); } ! void JavaFrameStream::next() { _vfst.next();} // Returns the BaseFrameStream for the current stack being traversed. // // Parameters: // thread Current Java thread. --- 64,153 ---- frames_array->obj_at_put(magic_pos, NULL); _anchor = 0L; return ok; } ! void BaseFrameStream::set_continuation(Handle cont) { ! // ensure that the lifetime of the handle is that of the entire walk ! // This actually also sets a copy of the handle in the RegisterMap, ! // but that's OK, because we want them to be the same, anyway. ! // (although we don't rely on this sharing, and set the other copy again) ! // tty->print_cr("-- BaseFrameStream::set_continuation: %p", (oopDesc*)cont()); ! *(_continuation.raw_value()) = cont(); ! } ! ! // static inline Handle continuation_of(Handle cont_or_scope) { ! // return (cont_or_scope.not_null() && cont_or_scope()->is_a(SystemDictionary::Continuation_klass())) ! // ? cont_or_scope ! // : Handle(); ! // } ! ! // static inline Handle continuationScope_of(JavaThread* thread, Handle cont_or_scope) { ! // if (cont_or_scope.is_null() || cont_or_scope()->is_a(SystemDictionary::ContinuationScope_klass())) ! // return cont_or_scope; ! // assert (cont_or_scope()->is_a(SystemDictionary::Continuation_klass()), "must be"); ! // return Handle(thread, Continuation::continuation_scope(cont_or_scope())); ! // } ! ! JavaFrameStream::JavaFrameStream(JavaThread* thread, int mode, Handle cont_scope, Handle cont) ! : BaseFrameStream(thread, cont), ! _vfst(cont.is_null() ! ? vframeStream(thread, cont_scope) ! : vframeStream(cont)) { _need_method_info = StackWalk::need_method_info(mode); } ! LiveFrameStream::LiveFrameStream(JavaThread* thread, RegisterMap* rm, Handle cont_scope, Handle cont) ! : BaseFrameStream(thread, cont), _cont_scope(cont_scope), ! _cont(cont.not_null() ? cont : Handle(thread, thread->last_continuation())) { ! ! _map = rm; ! if (cont.is_null()) { ! _jvf = thread->last_java_vframe(rm); ! // _cont = Handle(thread, thread->last_continuation()); ! } else { ! _jvf = Continuation::has_last_Java_frame(cont) ? Continuation::last_java_vframe(cont, rm) : NULL; ! // _cont = cont; ! } ! } ! ! void JavaFrameStream::set_continuation(Handle cont) { ! BaseFrameStream::set_continuation(cont); ! ! _vfst = vframeStream(continuation()); // we must not use the handle argument (lifetime; see BaseFrameStream::set_continuation) ! } ! ! void LiveFrameStream::set_continuation(Handle cont) { ! BaseFrameStream::set_continuation(cont); ! ! _jvf = Continuation::last_java_vframe(continuation(), _map); // we must not use the handle argument (lifetime; see BaseFrameStream::set_continuation) ! _cont = continuation(); // *(_cont.raw_value()) = cont(); // preserve handle ! tty->print_cr("-- LiveFrameStream::set_continuation: %p", (oopDesc*)_cont()); ! } ! ! void JavaFrameStream::next() { ! _vfst.next(); ! } ! ! void LiveFrameStream::next() { ! assert (_cont_scope.is_null() || _cont.not_null(), "must be"); ! if (_cont.not_null() && Continuation::is_continuation_entry_frame(_jvf->fr(), _jvf->register_map())) { ! oop cont = _cont(); ! oop scope = java_lang_Continuation::scope(cont); ! ! *(_cont.raw_value()) = java_lang_Continuation::parent(cont); ! ! if (_cont_scope.not_null() && oopDesc::equals(scope, _cont_scope())) { ! assert (Continuation::is_frame_in_continuation(_jvf->fr(), cont), "must be"); ! _jvf = NULL; ! return; ! } ! } ! assert (!Continuation::is_scope_bottom(_cont_scope(), _jvf->fr(), _jvf->register_map()), ""); ! ! _jvf = _jvf->java_sender(); ! } // Returns the BaseFrameStream for the current stack being traversed. // // Parameters: // thread Current Java thread.
*** 155,166 **** --- 234,255 ---- err_msg("StackWalker::getCallerClass called from @CallerSensitive '%s' method", method->external_name())); } // fill in StackFrameInfo and initialize MemberName stream.fill_frame(index, frames_array, method, CHECK_0); + + if (lt.is_enabled()) { + ResourceMark rm(THREAD); + LogStream ls(lt); + ls.print(" %d: done frame method: ", index); + method->print_short_name(&ls); + } + if (++frames_decoded >= max_nframes) break; } + log_debug(stackwalk)("fill_in_frames done frames_decoded=%d at_end=%d", frames_decoded, stream.at_end()); + return frames_decoded; } // Fill in the LiveStackFrameInfo at the given index in frames_array void LiveFrameStream::fill_frame(int index, objArrayHandle frames_array,
*** 278,288 **** return array_h; } // Fill StackFrameInfo with bci and initialize memberName void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) { ! java_lang_StackFrameInfo::set_method_and_bci(stackFrame, method, bci(), THREAD); } // Fill LiveStackFrameInfo with locals, monitors, and expressions void LiveFrameStream::fill_live_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) { --- 367,377 ---- return array_h; } // Fill StackFrameInfo with bci and initialize memberName void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) { ! java_lang_StackFrameInfo::set_method_and_bci(stackFrame, method, bci(), cont(), THREAD); } // Fill LiveStackFrameInfo with locals, monitors, and expressions void LiveFrameStream::fill_live_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) {
*** 319,359 **** // // Parameters: // stackStream StackStream object // mode Stack walking mode. // skip_frames Number of frames to be skipped. // frame_count Number of frames to be traversed. // start_index Start index to the user-supplied buffers. // frames_array Buffer to store StackFrame in, starting at start_index. // frames array is a Class<?>[] array when only getting caller // reference, and a StackFrameInfo[] array (or derivative) // otherwise. It should never be null. // // Returns Object returned from AbstractStackWalker::doStackWalk call. // ! oop StackWalk::walk(Handle stackStream, jlong mode, ! int skip_frames, int frame_count, int start_index, ! objArrayHandle frames_array, TRAPS) { ResourceMark rm(THREAD); JavaThread* jt = (JavaThread*)THREAD; ! log_debug(stackwalk)("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d", ! mode, skip_frames, frame_count); if (frames_array.is_null()) { THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL); } // Setup traversal onto my stack. if (live_frame_info(mode)) { assert (use_frames_array(mode), "Bad mode for get live frame"); ! RegisterMap regMap(jt, true); ! LiveFrameStream stream(jt, &regMap); return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, THREAD); } else { ! JavaFrameStream stream(jt, mode); return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, THREAD); } } --- 408,457 ---- // // Parameters: // stackStream StackStream object // mode Stack walking mode. // skip_frames Number of frames to be skipped. + // cont_scope Continuation scope to walk (if not in this scope, we'll walk all the way). // frame_count Number of frames to be traversed. // start_index Start index to the user-supplied buffers. // frames_array Buffer to store StackFrame in, starting at start_index. // frames array is a Class<?>[] array when only getting caller // reference, and a StackFrameInfo[] array (or derivative) // otherwise. It should never be null. // // Returns Object returned from AbstractStackWalker::doStackWalk call. // ! oop StackWalk::walk(Handle stackStream, jlong mode, int skip_frames, Handle cont_scope, Handle cont, ! int frame_count, int start_index, objArrayHandle frames_array, TRAPS) { ResourceMark rm(THREAD); + HandleMark hm(THREAD); // needed to store a continuation in the RegisterMap + JavaThread* jt = (JavaThread*)THREAD; ! log_debug(stackwalk)("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d", mode, skip_frames, frame_count); ! LogTarget(Debug, stackwalk) lt; ! if (lt.is_enabled()) { ! ResourceMark rm(THREAD); ! LogStream ls(lt); ! ls.print("cont_scope: "); ! cont_scope()->print_on(&ls); ! ls.cr(); ! } if (frames_array.is_null()) { THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL); } // Setup traversal onto my stack. if (live_frame_info(mode)) { assert (use_frames_array(mode), "Bad mode for get live frame"); ! RegisterMap regMap(jt, true, true); ! LiveFrameStream stream(jt, &regMap, cont_scope, cont); return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, THREAD); } else { ! JavaFrameStream stream(jt, mode, cont_scope, cont); return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, THREAD); } }
*** 449,459 **** // frames_array Buffer to store StackFrame in, starting at start_index. // // Returns the end index of frame filled in the buffer. // jint StackWalk::fetchNextBatch(Handle stackStream, jlong mode, jlong magic, ! int frame_count, int start_index, objArrayHandle frames_array, TRAPS) { JavaThread* jt = (JavaThread*)THREAD; BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array); --- 547,557 ---- // frames_array Buffer to store StackFrame in, starting at start_index. // // Returns the end index of frame filled in the buffer. // jint StackWalk::fetchNextBatch(Handle stackStream, jlong mode, jlong magic, ! int frame_count, int start_index, objArrayHandle frames_array, TRAPS) { JavaThread* jt = (JavaThread*)THREAD; BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array);
*** 488,492 **** --- 586,605 ---- return end_index; } } return end_index; } + + void StackWalk::setContinuation(Handle stackStream, jlong magic, objArrayHandle frames_array, Handle cont, TRAPS) { + JavaThread* jt = (JavaThread*)THREAD; + + if (frames_array.is_null()) { + THROW_MSG(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL"); + } + + BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array); + if (existing_stream == NULL) { + THROW_MSG(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers"); + } + + existing_stream->set_continuation(cont); + }
< prev index next >