< prev index next >

src/hotspot/cpu/x86/frame_x86.cpp

Print this page

        

*** 21,37 **** --- 21,39 ---- * questions. * */ #include "precompiled.hpp" + #include "compiler/oopMap.inline.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/markOop.hpp" #include "oops/method.hpp" #include "oops/oop.inline.hpp" #include "prims/methodHandles.hpp" + #include "runtime/continuation.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" #include "runtime/monitorChunk.hpp" #include "runtime/os.inline.hpp"
*** 150,159 **** --- 152,164 ---- sender_pc = (address) *(sender_sp-1); // Note: frame::sender_sp_offset is only valid for compiled frame saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset); } + if (Continuation::is_return_barrier_entry(sender_pc)) { + Continuation::fix_continuation_bottom_sender(thread, *this, &sender_pc, &sender_sp); + } // If the potential sender is the interpreter then we can do some more checking if (Interpreter::contains(sender_pc)) { // ebp is always saved in a recognizable place in any code we generate. However
*** 268,299 **** } void frame::patch_pc(Thread* thread, address pc) { address* pc_addr = &(((address*) sp())[-1]); if (TracePcPatching) { tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]", p2i(pc_addr), p2i(*pc_addr), p2i(pc)); } // Either the return address is the original one or we are going to // patch in the same address that's already there. ! assert(_pc == *pc_addr || pc == *pc_addr, "must be"); *pc_addr = pc; _cb = CodeCache::find_blob(pc); address original_pc = CompiledMethod::get_deopt_original_pc(this); if (original_pc != NULL) { ! assert(original_pc == _pc, "expected original PC to be stored before patching"); _deopt_state = is_deoptimized; ! // leave _pc as is } else { _deopt_state = not_deoptimized; - _pc = pc; } ! } ! bool frame::is_interpreted_frame() const { ! return Interpreter::contains(pc()); } int frame::frame_size(RegisterMap* map) const { frame sender = this->sender(map); return sender.sp() - sp(); --- 273,317 ---- } void frame::patch_pc(Thread* thread, address pc) { address* pc_addr = &(((address*) sp())[-1]); + pc_addr = Continuation::get_continuation_entry_pc_for_sender(thread, *this, pc_addr); + if (TracePcPatching) { tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]", p2i(pc_addr), p2i(*pc_addr), p2i(pc)); } // Either the return address is the original one or we are going to // patch in the same address that's already there. ! ! assert(!Continuation::is_return_barrier_entry(*pc_addr), "return barrier"); ! ! assert(_pc == *pc_addr || pc == *pc_addr || *pc_addr == 0, "must be (pc: " INTPTR_FORMAT " _pc: " INTPTR_FORMAT " pc_addr: " INTPTR_FORMAT " *pc_addr: " INTPTR_FORMAT ")", p2i(pc), p2i(_pc), p2i(pc_addr), p2i(*pc_addr)); ! DEBUG_ONLY(address old_pc = _pc;) *pc_addr = pc; _cb = CodeCache::find_blob(pc); + _pc = pc; // must be set before call to get_deopt_original_pc address original_pc = CompiledMethod::get_deopt_original_pc(this); if (original_pc != NULL) { ! assert(original_pc == old_pc, "expected original PC to be stored before patching"); _deopt_state = is_deoptimized; ! _pc = original_pc; } else { _deopt_state = not_deoptimized; } ! assert (!is_compiled_frame() || !_cb->as_compiled_method()->is_deopt_entry(_pc), "must be"); ! #ifdef ASSERT ! { ! frame f(this->sp(), this->unextended_sp(), this->fp(), pc); ! assert(f.is_deoptimized_frame() == this->is_deoptimized_frame() && f.pc() == this->pc() && f.raw_pc() == this->raw_pc(), ! "must be (f.is_deoptimized_frame(): %d this->is_deoptimized_frame(): %d " ! "f.pc(): " INTPTR_FORMAT " this->pc(): " INTPTR_FORMAT " f.raw_pc(): " INTPTR_FORMAT " this->raw_pc(): " INTPTR_FORMAT ")", ! f.is_deoptimized_frame(), this->is_deoptimized_frame(), p2i(f.pc()), p2i(this->pc()), p2i(f.raw_pc()), p2i(this->raw_pc())); ! } ! #endif } int frame::frame_size(RegisterMap* map) const { frame sender = this->sender(map); return sender.sp() - sp();
*** 327,337 **** BasicObjectLock* frame::interpreter_frame_monitor_end() const { BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset); // make sure the pointer points inside the frame assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer"); ! assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer"); return result; } void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) { *((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value; --- 345,355 ---- BasicObjectLock* frame::interpreter_frame_monitor_end() const { BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset); // make sure the pointer points inside the frame assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer"); ! assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer: result: " INTPTR_FORMAT " fp: " INTPTR_FORMAT, p2i(result), p2i(fp())); return result; } void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) { *((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value;
*** 376,386 **** // method anyway. fr._unextended_sp = unextended_sp; address original_pc = nm->get_original_pc(&fr); assert(nm->insts_contains_inclusive(original_pc), ! "original PC must be in the main code section of the the compiled method (or must be immediately following it)"); } #endif //------------------------------------------------------------------------------ // frame::adjust_unextended_sp --- 394,404 ---- // method anyway. fr._unextended_sp = unextended_sp; address original_pc = nm->get_original_pc(&fr); assert(nm->insts_contains_inclusive(original_pc), ! "original PC must be in the main code section of the the compiled method (or must be immediately following it) original_pc: " INTPTR_FORMAT " unextended_sp: " INTPTR_FORMAT " name: %s", p2i(original_pc), p2i(unextended_sp), nm->name()); } #endif //------------------------------------------------------------------------------ // frame::adjust_unextended_sp
*** 402,437 **** } } #endif //------------------------------------------------------------------------------ - // frame::update_map_with_saved_link - void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) { - // The interpreter and compiler(s) always save EBP/RBP in a known - // location on entry. We must record where that location is - // so this if EBP/RBP was live on callout from c2 we can find - // the saved copy no matter what it called. - - // Since the interpreter always saves EBP/RBP if we record where it is then - // we don't have to always save EBP/RBP on entry and exit to c2 compiled - // code, on entry will be enough. - map->set_location(rbp->as_VMReg(), (address) link_addr); - #ifdef AMD64 - // this is weird "H" ought to be at a higher address however the - // oopMaps seems to have the "H" regs at the same address and the - // vanilla register. - // XXXX make this go away - if (true) { - map->set_location(rbp->as_VMReg()->next(), (address) link_addr); - } - #endif // AMD64 - } - - - //------------------------------------------------------------------------------ // frame::sender_for_interpreter_frame frame frame::sender_for_interpreter_frame(RegisterMap* map) const { // SP is the raw SP from the sender after adapter or interpreter // extension. intptr_t* sender_sp = this->sender_sp(); // This is the sp before any possible extension (adapter/locals). --- 420,435 ---- } } #endif //------------------------------------------------------------------------------ // frame::sender_for_interpreter_frame frame frame::sender_for_interpreter_frame(RegisterMap* map) const { + if (map->in_cont()) { // already in an h-stack + return Continuation::sender_for_interpreter_frame(*this, map); + } + // SP is the raw SP from the sender after adapter or interpreter // extension. intptr_t* sender_sp = this->sender_sp(); // This is the sp before any possible extension (adapter/locals).
*** 441,508 **** if (map->update_map()) { update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); } #endif // COMPILER2_OR_JVMCI ! return frame(sender_sp, unextended_sp, link(), sender_pc()); ! } ! ! ! //------------------------------------------------------------------------------ ! // frame::sender_for_compiled_frame ! frame frame::sender_for_compiled_frame(RegisterMap* map) const { ! assert(map != NULL, "map must be set"); ! ! // frame owned by optimizing compiler ! assert(_cb->frame_size() >= 0, "must have non-zero frame size"); ! intptr_t* sender_sp = unextended_sp() + _cb->frame_size(); ! intptr_t* unextended_sp = sender_sp; ! ! // On Intel the return_address is always the word on the stack ! address sender_pc = (address) *(sender_sp-1); ! ! // This is the saved value of EBP which may or may not really be an FP. ! // It is only an FP if the sender is an interpreter frame (or C1?). ! intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset); ! if (map->update_map()) { ! // Tell GC to use argument oopmaps for some runtime stubs that need it. ! // For C1, the runtime stub might not have oop maps, so set this flag ! // outside of update_register_map. ! map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread())); ! if (_cb->oop_maps() != NULL) { ! OopMapSet::update_register_map(this, map); ! } ! ! // Since the prolog does the save and restore of EBP there is no oopmap ! // for it so we must fill in its location as if there was an oopmap entry ! // since if our caller was compiled code there could be live jvm state in it. ! update_map_with_saved_link(map, saved_fp_addr); } ! ! assert(sender_sp != sp(), "must have changed"); ! return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc); } //------------------------------------------------------------------------------ // frame::sender frame frame::sender(RegisterMap* map) const { ! // Default is we done have to follow them. The sender_for_xxx will ! // update it accordingly ! map->set_include_argument_oops(false); ! ! if (is_entry_frame()) return sender_for_entry_frame(map); ! if (is_interpreted_frame()) return sender_for_interpreter_frame(map); ! assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); ! ! if (_cb != NULL) { ! return sender_for_compiled_frame(map); ! } ! // Must be native-compiled frame, i.e. the marshaling code for native ! // methods that exists in the core system. ! return frame(sender_sp(), link(), sender_pc()); } bool frame::is_interpreted_frame_valid(JavaThread* thread) const { assert(is_interpreted_frame(), "Not an interpreted frame"); // These are reasonable sanity checks --- 439,465 ---- if (map->update_map()) { update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); } #endif // COMPILER2_OR_JVMCI ! address sender_pc = this->sender_pc(); ! if (Continuation::is_return_barrier_entry(sender_pc)) { ! if (map->walk_cont()) { // about to walk into an h-stack ! return Continuation::top_frame(*this, map); ! } else { ! Continuation::fix_continuation_bottom_sender(map, *this, &sender_pc, NULL); ! } } ! return frame(sender_sp, unextended_sp, link(), sender_pc); // Continuation::fix_continuation_bottom_sender(*this, map, frame(sender_sp, unextended_sp, link(), sender_pc)); } //------------------------------------------------------------------------------ // frame::sender frame frame::sender(RegisterMap* map) const { ! return frame_sender<CodeCache>(map); } bool frame::is_interpreted_frame_valid(JavaThread* thread) const { assert(is_interpreted_frame(), "Not an interpreted frame"); // These are reasonable sanity checks
*** 632,642 **** } #ifndef PRODUCT #define DESCRIBE_FP_OFFSET(name) \ ! values.describe(frame_no, fp() + frame::name##_offset, #name) void frame::describe_pd(FrameValues& values, int frame_no) { if (is_interpreted_frame()) { DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp); DESCRIBE_FP_OFFSET(interpreter_frame_last_sp); --- 589,599 ---- } #ifndef PRODUCT #define DESCRIBE_FP_OFFSET(name) \ ! values.describe(frame_no, fp() + frame::name##_offset, #name, 1) void frame::describe_pd(FrameValues& values, int frame_no) { if (is_interpreted_frame()) { DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp); DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
*** 645,654 **** --- 602,614 ---- DESCRIBE_FP_OFFSET(interpreter_frame_mdp); DESCRIBE_FP_OFFSET(interpreter_frame_cache); DESCRIBE_FP_OFFSET(interpreter_frame_locals); DESCRIBE_FP_OFFSET(interpreter_frame_bcp); DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp); + } else if (is_compiled_frame()) { + values.describe(frame_no, real_fp() - return_addr_offset, "return address"); + values.describe(frame_no, real_fp() - sender_sp_offset, "saved fp", 2); #ifdef AMD64 } else if (is_entry_frame()) { // This could be more descriptive if we use the enum in // stubGenerator to map to real names but it's most important to // claim these frame slots so the error checking works.
*** 663,685 **** intptr_t *frame::initial_deoptimization_info() { // used to reset the saved FP return fp(); } - intptr_t* frame::real_fp() const { - if (_cb != NULL) { - // use the frame size if valid - int size = _cb->frame_size(); - if (size > 0) { - return unextended_sp() + size; - } - } - // else rely on fp() - assert(! is_compiled_frame(), "unknown compiled frame size"); - return fp(); - } - #ifndef PRODUCT // This is a generic constructor which is only used by pns() in debug.cpp. frame::frame(void* sp, void* fp, void* pc) { init((intptr_t*)sp, (intptr_t*)fp, (address)pc); } --- 623,632 ----
< prev index next >