*** 144,17 *** sender_sp = _unextended_sp + _cb->frame_size(); // Is sender_sp safe? if (!thread->is_in_full_stack_checked((address)sender_sp)) { return false; } - sender_unextended_sp = sender_sp; // On Intel the return_address is always the word on the stack 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)) { // If our sender_pc is the return barrier, then our "real" sender is the continuation entry frame s = Continuation::continuation_bottom_sender(thread, *this, sender_sp); sender_sp = s.sp(); sender_pc = s.pc(); --- 144,20 --- sender_sp = _unextended_sp + _cb->frame_size(); // Is sender_sp safe? if (!thread->is_in_full_stack_checked((address)sender_sp)) { return false; } // On Intel the return_address is always the word on the stack sender_pc = (address) *(sender_sp-1); // Note: frame::sender_sp_offset is only valid for compiled frame ! intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset); ! saved_fp = *saved_fp_addr; + // Repair the sender sp if this is a method with scalarized inline type args + sender_sp = repair_sender_sp(sender_sp, saved_fp_addr); + sender_unextended_sp = sender_sp; + } if (Continuation::is_return_barrier_entry(sender_pc)) { // If our sender_pc is the return barrier, then our "real" sender is the continuation entry frame s = Continuation::continuation_bottom_sender(thread, *this, sender_sp); sender_sp = s.sp(); sender_pc = s.pc();
*** 554,10 *** --- 557,11 --- tos_addr = (intptr_t*)interpreter_frame_tos_address(); } switch (type) { case T_OBJECT : + case T_PRIMITIVE_OBJECT: // fall through case T_ARRAY : { oop obj; if (method->is_native()) { obj = cast_to_oop(at(interpreter_frame_oop_temp_offset)); } else {
*** 657,10 *** --- 661,25 --- init((intptr_t*)sp, (intptr_t*)fp, (address)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 { + CompiledMethod* cm = _cb->as_compiled_method_or_null(); + if (cm != nullptr && cm->needs_stack_repair()) { + // The stack increment resides just below the saved rbp on the stack + // and does not account for the return address. + intptr_t* real_frame_size_addr = (intptr_t*) (saved_fp_addr - 1); + int real_frame_size = ((*real_frame_size_addr) + wordSize) / wordSize; + assert(real_frame_size >= _cb->frame_size() && real_frame_size <= 1000000, "invalid frame size"); + sender_sp = unextended_sp() + real_frame_size; + } + return sender_sp; + } + void JavaFrameAnchor::make_walkable() { // last frame set? if (last_Java_sp() == nullptr) return; // already walkable? if (walkable()) return;