< prev index next >

src/cpu/x86/vm/frame_x86.inline.hpp

Print this page

        

*** 38,48 **** _fp = NULL; _cb = NULL; _deopt_state = unknown; } ! inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) { _sp = sp; _unextended_sp = sp; _fp = fp; _pc = pc; assert(pc != NULL, "no pc?"); --- 38,52 ---- _fp = NULL; _cb = NULL; _deopt_state = unknown; } ! inline void frame::init(Thread* thread, intptr_t* sp, intptr_t* fp, address pc) { ! if (thread != NULL && thread->is_Java_thread() && SharedRuntime::is_memento_stack_trace_return_handler(pc)) { ! pc = ((JavaThread*) thread)->memento_original_return_address(); ! } ! _sp = sp; _unextended_sp = sp; _fp = fp; _pc = pc; assert(pc != NULL, "no pc?");
*** 54,70 **** _pc = original_pc; _deopt_state = is_deoptimized; } else { _deopt_state = not_deoptimized; } } ! inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) { ! init(sp, fp, pc); } ! inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) { _sp = sp; _unextended_sp = unextended_sp; _fp = fp; _pc = pc; assert(pc != NULL, "no pc?"); --- 58,80 ---- _pc = original_pc; _deopt_state = is_deoptimized; } else { _deopt_state = not_deoptimized; } + + assert(!SharedRuntime::is_memento_stack_trace_return_handler(_pc), "original return address not resolvable"); } ! inline frame::frame(Thread* thread, intptr_t* sp, intptr_t* fp, address pc) { ! init(thread, sp, fp, pc); } ! inline frame::frame(Thread* thread, intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) { ! if (thread != NULL && thread->is_Java_thread() && SharedRuntime::is_memento_stack_trace_return_handler(pc)) { ! pc = ((JavaThread*) thread)->memento_original_return_address(); ! } ! _sp = sp; _unextended_sp = unextended_sp; _fp = fp; _pc = pc; assert(pc != NULL, "no pc?");
*** 77,94 **** assert(((nmethod*)_cb)->insts_contains(_pc), "original PC must be in nmethod"); _deopt_state = is_deoptimized; } else { _deopt_state = not_deoptimized; } } ! inline frame::frame(intptr_t* sp, intptr_t* fp) { _sp = sp; _unextended_sp = sp; _fp = fp; _pc = (address)(sp[-1]); // Here's a sticky one. This constructor can be called via AsyncGetCallTrace // when last_Java_sp is non-null but the pc fetched is junk. If we are truly // unlucky the junk value could be to a zombied method and we'll die on the // find_blob call. This is also why we can have no asserts on the validity // of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler --- 87,110 ---- assert(((nmethod*)_cb)->insts_contains(_pc), "original PC must be in nmethod"); _deopt_state = is_deoptimized; } else { _deopt_state = not_deoptimized; } + + assert(!SharedRuntime::is_memento_stack_trace_return_handler(_pc), "original return address not resolvable"); } ! inline frame::frame(Thread* thread, intptr_t* sp, intptr_t* fp) { _sp = sp; _unextended_sp = sp; _fp = fp; _pc = (address)(sp[-1]); + if (thread != NULL && thread->is_Java_thread() && SharedRuntime::is_memento_stack_trace_return_handler(_pc)) { + _pc = ((JavaThread*) thread)->memento_original_return_address(); + } + // Here's a sticky one. This constructor can be called via AsyncGetCallTrace // when last_Java_sp is non-null but the pc fetched is junk. If we are truly // unlucky the junk value could be to a zombied method and we'll die on the // find_blob call. This is also why we can have no asserts on the validity // of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
*** 106,115 **** --- 122,133 ---- _pc = original_pc; _deopt_state = is_deoptimized; } else { _deopt_state = not_deoptimized; } + + assert(!SharedRuntime::is_memento_stack_trace_return_handler(_pc), "original return address not resolvable"); } // Accessors inline bool frame::equal(frame other) const {
*** 314,319 **** --- 332,377 ---- guarantee(result_adr != NULL, "bad register save location"); *result_adr = obj; } + inline address* frame::raw_sender_pc_addr() { + address* sender_pc; + + if (is_interpreted_frame()) { + sender_pc = sender_pc_addr(); + assert(interpreter_frame_sender_sp() > (intptr_t*) sender_pc, "sender_sp should be below return address"); + } else { + assert(_cb != NULL, "code blob is required"); + assert(is_compiled_frame() || is_native_frame() || is_stub_frame(), "unexpected frame type"); + + // frame owned by optimizing compiler + int frame_size = _cb->frame_size(); + assert(frame_size > 0, "must have non-zero frame size"); + intptr_t* sender_sp = unextended_sp() + frame_size; + + // On Intel the return_address is always the word on the stack + sender_pc = (address*) sender_sp-1; + } + assert(CodeCache::contains(*sender_pc), "must be in code cache"); + + return sender_pc; + } + + inline void frame::memento_mark(Thread* thread) { + address& original_return_address = thread->memento_original_return_address(); + assert(original_return_address == NULL, "only 1 frame can be patched per thread"); + + address* sender_pc = raw_sender_pc_addr(); + original_return_address = *sender_pc; + *sender_pc = SharedRuntime::get_memento_stack_trace_return_handler(); + } + + inline bool frame::is_memento_marked(Thread* thread) { + bool memento_marked = *raw_sender_pc_addr() == SharedRuntime::get_memento_stack_trace_return_handler(); + if (memento_marked) { + assert(thread->memento_original_return_address() != NULL, "original return address must be set if frame is patched"); + } + return memento_marked; + } + #endif // CPU_X86_VM_FRAME_X86_INLINE_HPP
< prev index next >