diff --git a/src/hotspot/cpu/x86/frame_x86.cpp b/src/hotspot/cpu/x86/frame_x86.cpp index 087833d1411..746fe62b4f0 100644 --- a/src/hotspot/cpu/x86/frame_x86.cpp +++ b/src/hotspot/cpu/x86/frame_x86.cpp @@ -649,41 +649,6 @@ frame::frame(void* sp, void* fp, void* pc) { #endif -// Check for a method with scalarized inline type arguments that needs -// a stack repair and return the repaired sender stack pointer. -intptr_t* frame::repair_sender_sp(intptr_t* sender_sp, intptr_t** saved_fp_addr) const { - nmethod* nm = _cb->as_nmethod_or_null(); - if (nm != nullptr && nm->needs_stack_repair()) { - // The stack increment resides just below the saved rbp on the stack - // and does not account for the return address and rbp (see MacroAssembler::remove_frame). - intptr_t* real_frame_size_addr = (intptr_t*) (saved_fp_addr - 1); - int real_frame_size = (*real_frame_size_addr / wordSize) + metadata_words_at_bottom; - assert(real_frame_size >= _cb->frame_size() && real_frame_size <= 1000000, "invalid frame size"); - sender_sp = unextended_sp() + real_frame_size; - } - return sender_sp; -} - - -// See comment in MacroAssembler::remove_frame -frame::CompiledFramePointers frame::compiled_frame_details() const { - // 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(); - assert(sender_sp == real_fp(), ""); - - // Repair the sender sp if the frame has been extended - sender_sp = repair_sender_sp(sender_sp, (intptr_t**)(sender_sp - frame::sender_sp_offset)); - - CompiledFramePointers cfp; - cfp.sender_sp = sender_sp; - cfp.saved_fp_addr = (intptr_t**)(sender_sp - frame::sender_sp_offset); - // On Intel the return_address is always the word on the stack - cfp.sender_pc_addr = (address*)(sender_sp - frame::return_addr_offset); - - return cfp; -} - intptr_t* frame::repair_sender_sp(nmethod* nm, intptr_t* sp, intptr_t** saved_fp_addr) { assert(nm != nullptr && nm->needs_stack_repair(), ""); // The stack increment resides just below the saved rbp on the stack diff --git a/src/hotspot/cpu/x86/frame_x86.hpp b/src/hotspot/cpu/x86/frame_x86.hpp index 7d7dacc17f7..425469ea10a 100644 --- a/src/hotspot/cpu/x86/frame_x86.hpp +++ b/src/hotspot/cpu/x86/frame_x86.hpp @@ -138,13 +138,13 @@ public: // Support for scalarized inline type calling convention - intptr_t* repair_sender_sp(intptr_t* sender_sp, intptr_t** saved_fp_addr) const; + ALWAYSINLINE intptr_t* repair_sender_sp(intptr_t* sender_sp, intptr_t** saved_fp_addr) const; struct CompiledFramePointers { intptr_t* sender_sp; // The top of the stack of the sender intptr_t** saved_fp_addr; // Where RBP is saved on the stack address* sender_pc_addr; // Where return address (copy #1 in remove_frame's comment) is saved on the stack }; - CompiledFramePointers compiled_frame_details() const; + ALWAYSINLINE CompiledFramePointers compiled_frame_details() const; static intptr_t* repair_sender_sp(nmethod* nm, intptr_t* sp, intptr_t** saved_fp_addr); bool was_augmented_on_entry(int& real_size) const; @@ -182,6 +182,6 @@ void interpreter_frame_set_last_sp(intptr_t* sp); // returns the sending frame, without applying any barriers - inline frame sender_raw(RegisterMap* map) const; + ALWAYSINLINE frame sender_raw(RegisterMap* map) const; #endif // CPU_X86_FRAME_X86_HPP diff --git a/src/hotspot/cpu/x86/frame_x86.inline.hpp b/src/hotspot/cpu/x86/frame_x86.inline.hpp index d7cb1db9b03..2dbcb647ea9 100644 --- a/src/hotspot/cpu/x86/frame_x86.inline.hpp +++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp @@ -393,7 +393,7 @@ inline int frame::sender_sp_ret_address_offset() { //------------------------------------------------------------------------------ // frame::sender -inline frame frame::sender(RegisterMap* map) const { +ALWAYSINLINE frame frame::sender(RegisterMap* map) const { frame result = sender_raw(map); if (map->process_frames() && !map->in_cont()) { @@ -406,7 +406,7 @@ inline frame frame::sender(RegisterMap* map) const { return result; } -inline frame frame::sender_raw(RegisterMap* map) const { +ALWAYSINLINE frame frame::sender_raw(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); @@ -427,7 +427,42 @@ inline frame frame::sender_raw(RegisterMap* map) const { return frame(sender_sp(), link(), sender_pc()); } -inline frame frame::sender_for_compiled_frame(RegisterMap* map) const { +// Check for a method with scalarized inline type arguments that needs +// a stack repair and return the repaired sender stack pointer. +ALWAYSINLINE intptr_t* frame::repair_sender_sp(intptr_t* sender_sp, intptr_t** saved_fp_addr) const { + nmethod* nm = _cb->as_nmethod_or_null(); + if (nm != nullptr && nm->needs_stack_repair()) { + // The stack increment resides just below the saved rbp on the stack + // and does not account for the return address and rbp (see MacroAssembler::remove_frame). + intptr_t* real_frame_size_addr = (intptr_t*) (saved_fp_addr - 1); + int real_frame_size = (*real_frame_size_addr / wordSize) + metadata_words_at_bottom; + assert(real_frame_size >= _cb->frame_size() && real_frame_size <= 1000000, "invalid frame size"); + sender_sp = unextended_sp() + real_frame_size; + } + return sender_sp; +} + + +// See comment in MacroAssembler::remove_frame +ALWAYSINLINE frame::CompiledFramePointers frame::compiled_frame_details() const { + // 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(); + assert(sender_sp == real_fp(), ""); + + // Repair the sender sp if the frame has been extended + sender_sp = repair_sender_sp(sender_sp, (intptr_t**)(sender_sp - frame::sender_sp_offset)); + + CompiledFramePointers cfp; + cfp.sender_sp = sender_sp; + cfp.saved_fp_addr = (intptr_t**)(sender_sp - frame::sender_sp_offset); + // On Intel the return_address is always the word on the stack + cfp.sender_pc_addr = (address*)(sender_sp - frame::return_addr_offset); + + return cfp; +} + +ALWAYSINLINE frame frame::sender_for_compiled_frame(RegisterMap* map) const { assert(map != nullptr, "map must be set"); CompiledFramePointers cfp = compiled_frame_details(); diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index 02fcc3ea72e..0ef5cb1abd7 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -1062,6 +1062,10 @@ void ciEnv::register_method(ciMethod* target, assert(compiler->type() == compiler_c2 || offsets->value(CodeOffsets::Exceptions) != -1, "must have exception entry"); + bool needs_stack_repair = + (compiler->is_c1() && method()->c1_needs_stack_repair()) || + (compiler->is_c2() && method()->c2_needs_stack_repair()); + nm = nmethod::new_nmethod(method, compile_id(), entry_bci, @@ -1071,7 +1075,7 @@ void ciEnv::register_method(ciMethod* target, frame_words, oop_map_set, handler_table, inc_table, compiler, CompLevel(task()->comp_level()), - nmethod::Flags(has_unsafe_access, has_wide_vectors, has_monitors, has_scoped_access)); + nmethod::Flags(has_unsafe_access, has_wide_vectors, has_monitors, has_scoped_access, needs_stack_repair)); // Free codeBlobs code_buffer->free_blob(); diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index 217dd60dcab..959e6baac3a 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -259,17 +259,19 @@ public: enum : uint8_t { UNSAFE_ACCESS = 1 << 0, - WIDE_VECTORS = 1 << 1, - MONITORS = 1 << 2, - SCOPED_ACCESS = 1 << 3 + WIDE_VECTORS = 1 << 1, + MONITORS = 1 << 2, + SCOPED_ACCESS = 1 << 3, + NEEDS_STACK_REPAIR = 1 << 4, }; Flags() : _bits(0) {} - Flags(bool has_unsafe_access, bool has_wide_vectors, bool has_monitors, bool has_scoped_access) : + Flags(bool has_unsafe_access, bool has_wide_vectors, bool has_monitors, bool has_scoped_access, bool needs_stack_repair) : _bits((has_unsafe_access ? UNSAFE_ACCESS : 0) | - (has_wide_vectors ? WIDE_VECTORS : 0) | - (has_monitors ? MONITORS : 0) | - (has_scoped_access ? SCOPED_ACCESS : 0)) + (has_wide_vectors ? WIDE_VECTORS : 0) | + (has_monitors ? MONITORS : 0) | + (has_scoped_access ? SCOPED_ACCESS : 0) | + (needs_stack_repair ? NEEDS_STACK_REPAIR : 0)) {} // May fault due to unsafe access @@ -283,6 +285,9 @@ public: // Used by shared scope closure (scopedMemoryAccess.cpp) bool has_scoped_access() const { return (_bits & SCOPED_ACCESS) != 0; } + + // Used by shared scope closure (scopedMemoryAccess.cpp) + bool needs_stack_repair() const { return (_bits & NEEDS_STACK_REPAIR) != 0; } }; private: @@ -739,16 +744,7 @@ public: bool has_monitors() const { return _flags.has_monitors(); } bool has_scoped_access() const { return _flags.has_scoped_access(); } bool has_wide_vectors() const { return _flags.has_wide_vectors(); } - - bool needs_stack_repair() const { - if (is_compiled_by_c1()) { - return method()->c1_needs_stack_repair(); - } else if (is_compiled_by_c2()) { - return method()->c2_needs_stack_repair(); - } else { - return false; - } - } + bool needs_stack_repair() const { return _flags.needs_stack_repair(); } bool has_flushed_dependencies() const { return _has_flushed_dependencies; } void set_has_flushed_dependencies(bool z) { diff --git a/src/hotspot/share/runtime/frame.hpp b/src/hotspot/share/runtime/frame.hpp index a9cfacc1241..7961ff8f9c3 100644 --- a/src/hotspot/share/runtime/frame.hpp +++ b/src/hotspot/share/runtime/frame.hpp @@ -226,7 +226,7 @@ class frame { inline void interpreted_frame_oop_map(InterpreterOopMap* mask) const; // returns the sending frame - inline frame sender(RegisterMap* map) const; + ALWAYSINLINE frame sender(RegisterMap* map) const; bool safe_for_sender(JavaThread *thread); @@ -239,7 +239,7 @@ class frame { private: // Helper methods for better factored code in frame::sender - inline frame sender_for_compiled_frame(RegisterMap* map) const; + ALWAYSINLINE frame sender_for_compiled_frame(RegisterMap* map) const; frame sender_for_entry_frame(RegisterMap* map) const; frame sender_for_interpreter_frame(RegisterMap* map) const; frame sender_for_upcall_stub_frame(RegisterMap* map) const;