*** 143,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)) { // sender_pc might be invalid so check that the frame // actually belongs to a Continuation. if (!Continuation::is_frame_in_continuation(thread, *this)) { return false; --- 143,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)) { // sender_pc might be invalid so check that the frame // actually belongs to a Continuation. if (!Continuation::is_frame_in_continuation(thread, *this)) { return false;
*** 671,10 *** --- 674,13 --- ret_pc_loc = fp() + return_addr_offset; fp_loc = fp(); } else { ret_pc_loc = real_fp() - return_addr_offset; fp_loc = real_fp() - sender_sp_offset; + if (cb()->is_nmethod() && cb()->as_nmethod_or_null()->needs_stack_repair()) { + values.describe(frame_no, fp_loc - 1, err_msg("fsize for #%d", frame_no), 1); + } } address ret_pc = *(address*)ret_pc_loc; values.describe(frame_no, ret_pc_loc, Continuation::is_return_barrier_entry(ret_pc) ? "return address (return barrier)" : "return address"); values.describe(-1, fp_loc, "saved fp", 0); // "unowned" as value belongs to sender
*** 694,10 *** --- 700,47 --- 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 { + 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. + 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; + } + + 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 + // 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 >= nm->frame_size() && real_frame_size <= 1000000, "invalid frame size"); + return sp + real_frame_size; + } + + bool frame::was_augmented_on_entry(int& real_size) const { + assert(is_compiled_frame(), ""); + if (_cb->as_nmethod_or_null()->needs_stack_repair()) { + intptr_t* real_frame_size_addr = unextended_sp() + _cb->frame_size() - sender_sp_offset - 1; + log_trace(continuations)("real_frame_size is addr is " INTPTR_FORMAT, p2i(real_frame_size_addr)); + real_size = ((*real_frame_size_addr) + wordSize) / wordSize; + return real_size != _cb->frame_size(); + } + real_size = _cb->frame_size(); + return false; + } + void JavaFrameAnchor::make_walkable() { // last frame set? if (last_Java_sp() == nullptr) return; // already walkable? if (walkable()) return;