< prev index next >

src/hotspot/share/runtime/vframe.hpp

Print this page

        

*** 28,38 **** #include "code/debugInfo.hpp" #include "code/debugInfoRec.hpp" #include "code/location.hpp" #include "oops/oop.hpp" #include "runtime/frame.hpp" - #include "runtime/frame.inline.hpp" #include "runtime/stackValue.hpp" #include "runtime/stackValueCollection.hpp" #include "utilities/growableArray.hpp" // vframes are virtual stack frames representing source level activations. --- 28,37 ----
*** 305,344 **** DEBUG_ONLY(void found_bad_method_frame() const;) public: // Constructor ! vframeStreamCommon(JavaThread* thread) : _reg_map(thread, false) { ! _thread = thread; ! } // Accessors Method* method() const { return _method; } int bci() const { return _bci; } ! intptr_t* frame_id() const { return _frame.id(); } address frame_pc() const { return _frame.pc(); } CodeBlob* cb() const { return _frame.cb(); } CompiledMethod* nm() const { assert( cb() != NULL && cb()->is_compiled(), "usage"); return (CompiledMethod*) cb(); } // Frame type ! bool is_interpreted_frame() const { return _frame.is_interpreted_frame(); } ! bool is_entry_frame() const { return _frame.is_entry_frame(); } // Iteration ! void next() { ! // handle frames with inlining ! if (_mode == compiled_mode && fill_in_compiled_inlined_sender()) return; ! ! // handle general case ! do { ! _frame = _frame.sender(&_reg_map); ! } while (!fill_from_frame()); ! } void security_next(); bool at_end() const { return _mode == at_end_mode; } // Implements security traversal. Skips depth no. of frame including --- 304,333 ---- DEBUG_ONLY(void found_bad_method_frame() const;) public: // Constructor ! vframeStreamCommon(JavaThread* thread); // Accessors Method* method() const { return _method; } int bci() const { return _bci; } ! intptr_t* frame_id() const; address frame_pc() const { return _frame.pc(); } CodeBlob* cb() const { return _frame.cb(); } CompiledMethod* nm() const { assert( cb() != NULL && cb()->is_compiled(), "usage"); return (CompiledMethod*) cb(); } // Frame type ! bool is_interpreted_frame() const; ! bool is_entry_frame() const; // Iteration ! void next(); void security_next(); bool at_end() const { return _mode == at_end_mode; } // Implements security traversal. Skips depth no. of frame including
*** 351,534 **** }; class vframeStream : public vframeStreamCommon { public: // Constructors ! vframeStream(JavaThread* thread, bool stop_at_java_call_stub = false) ! : vframeStreamCommon(thread) { ! _stop_at_java_call_stub = stop_at_java_call_stub; ! ! if (!thread->has_last_Java_frame()) { ! _mode = at_end_mode; ! return; ! } ! ! _frame = _thread->last_frame(); ! while (!fill_from_frame()) { ! _frame = _frame.sender(&_reg_map); ! } ! } // top_frame may not be at safepoint, start with sender vframeStream(JavaThread* thread, frame top_frame, bool stop_at_java_call_stub = false); }; - - inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() { - if (_sender_decode_offset == DebugInformationRecorder::serialized_null) { - return false; - } - fill_from_compiled_frame(_sender_decode_offset); - return true; - } - - - inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) { - _mode = compiled_mode; - - // Range check to detect ridiculous offsets. - if (decode_offset == DebugInformationRecorder::serialized_null || - decode_offset < 0 || - decode_offset >= nm()->scopes_data_size()) { - // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. - // If we read nmethod::scopes_data at serialized_null (== 0) - // or if read some at other invalid offset, invalid values will be decoded. - // Based on these values, invalid heap locations could be referenced - // that could lead to crashes in product mode. - // Therefore, do not use the decode offset if invalid, but fill the frame - // as it were a native compiled frame (no Java-level assumptions). - #ifdef ASSERT - if (WizardMode) { - ttyLocker ttyl; - tty->print_cr("Error in fill_from_frame: pc_desc for " - INTPTR_FORMAT " not found or invalid at %d", - p2i(_frame.pc()), decode_offset); - nm()->print(); - nm()->method()->print_codes(); - nm()->print_code(); - nm()->print_pcs(); - } - found_bad_method_frame(); - #endif - // Provide a cheap fallback in product mode. (See comment above.) - fill_from_compiled_native_frame(); - return; - } - - // Decode first part of scopeDesc - DebugInfoReadStream buffer(nm(), decode_offset); - _sender_decode_offset = buffer.read_int(); - _method = buffer.read_method(); - _bci = buffer.read_bci(); - - assert(_method->is_method(), "checking type of decoded method"); - } - - // The native frames are handled specially. We do not rely on ScopeDesc info - // since the pc might not be exact due to the _last_native_pc trick. - inline void vframeStreamCommon::fill_from_compiled_native_frame() { - _mode = compiled_mode; - _sender_decode_offset = DebugInformationRecorder::serialized_null; - _method = nm()->method(); - _bci = 0; - } - - inline bool vframeStreamCommon::fill_from_frame() { - // Interpreted frame - if (_frame.is_interpreted_frame()) { - fill_from_interpreter_frame(); - return true; - } - - // Compiled frame - - if (cb() != NULL && cb()->is_compiled()) { - if (nm()->is_native_method()) { - // Do not rely on scopeDesc since the pc might be unprecise due to the _last_native_pc trick. - fill_from_compiled_native_frame(); - } else { - PcDesc* pc_desc = nm()->pc_desc_at(_frame.pc()); - int decode_offset; - if (pc_desc == NULL) { - // Should not happen, but let fill_from_compiled_frame handle it. - - // If we are trying to walk the stack of a thread that is not - // at a safepoint (like AsyncGetCallTrace would do) then this is an - // acceptable result. [ This is assuming that safe_for_sender - // is so bullet proof that we can trust the frames it produced. ] - // - // So if we see that the thread is not safepoint safe - // then simply produce the method and a bci of zero - // and skip the possibility of decoding any inlining that - // may be present. That is far better than simply stopping (or - // asserting. If however the thread is safepoint safe this - // is the sign of a compiler bug and we'll let - // fill_from_compiled_frame handle it. - - - JavaThreadState state = _thread->thread_state(); - - // in_Java should be good enough to test safepoint safety - // if state were say in_Java_trans then we'd expect that - // the pc would have already been slightly adjusted to - // one that would produce a pcDesc since the trans state - // would be one that might in fact anticipate a safepoint - - if (state == _thread_in_Java ) { - // This will get a method a zero bci and no inlining. - // Might be nice to have a unique bci to signify this - // particular case but for now zero will do. - - fill_from_compiled_native_frame(); - - // There is something to be said for setting the mode to - // at_end_mode to prevent trying to walk further up the - // stack. There is evidence that if we walk any further - // that we could produce a bad stack chain. However until - // we see evidence that allowing this causes us to find - // frames bad enough to cause segv's or assertion failures - // we don't do it as while we may get a bad call chain the - // probability is much higher (several magnitudes) that we - // get good data. - - return true; - } - decode_offset = DebugInformationRecorder::serialized_null; - } else { - decode_offset = pc_desc->scope_decode_offset(); - } - fill_from_compiled_frame(decode_offset); - } - return true; - } - - // End of stack? - if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) { - _mode = at_end_mode; - return true; - } - - return false; - } - - - inline void vframeStreamCommon::fill_from_interpreter_frame() { - Method* method = _frame.interpreter_frame_method(); - address bcp = _frame.interpreter_frame_bcp(); - int bci = method->validate_bci_from_bcp(bcp); - // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. - // AsyncGetCallTrace interrupts the VM asynchronously. As a result - // it is possible to access an interpreter frame for which - // no Java-level information is yet available (e.g., becasue - // the frame was being created when the VM interrupted it). - // In this scenario, pretend that the interpreter is at the point - // of entering the method. - if (bci < 0) { - DEBUG_ONLY(found_bad_method_frame();) - bci = 0; - } - _mode = interpreted_mode; - _method = method; - _bci = bci; - } - #endif // SHARE_VM_RUNTIME_VFRAME_HPP --- 340,351 ---- }; class vframeStream : public vframeStreamCommon { public: // Constructors ! vframeStream(JavaThread* thread, bool stop_at_java_call_stub = false); // top_frame may not be at safepoint, start with sender vframeStream(JavaThread* thread, frame top_frame, bool stop_at_java_call_stub = false); }; #endif // SHARE_VM_RUNTIME_VFRAME_HPP
< prev index next >