Commit 07ee3ac7 authored by Mu Tao's avatar Mu Tao Committed by Commit Bot

[mips][wasm] Add an additional stack check for functions with big frames

Port 9f01d5c1

Original Commit Message:

    Stack overflow checks are typically implemented as part of the TurboFan
    graph of a function. This means that the stack check code is executed
    after frame construction. When a frame is too big, though, there may not
    be enough space on the stack anymore to throw the stack overflow
    exception after frame construction. With this CL we do an additional
    stack check before frame construction for functions with big frames.

    As discussed offline with mstarzinger, I do this change currently only
    for WebAssembly.

    This CL contains only the changes for arm. I will do the other platforms
    in separate CLs

R=xwafish@gmail.com

Change-Id: I46c6dd8fac1385e5da13e03cfffd9c640a7c2c57
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1792582
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Auto-Submit: Mu Tao <pamilty@gmail.com>
Cr-Commit-Position: refs/heads/master@{#63632}
parent 83729f18
......@@ -3452,6 +3452,42 @@ void CodeGenerator::AssembleConstructFrame() {
const RegList saves = call_descriptor->CalleeSavedRegisters();
const RegList saves_fpu = call_descriptor->CalleeSavedFPRegisters();
if (required_slots > 0) {
DCHECK(frame_access_state()->has_frame());
if (info()->IsWasm() && required_slots > 128) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
// have enough space on the stack to call the runtime for the stack
// overflow.
Label done;
// If the frame is bigger than the stack, we throw the stack overflow
// exception unconditionally. Thereby we can avoid the integer overflow
// check in the condition code.
if ((required_slots * kSystemPointerSize) < (FLAG_stack_size * 1024)) {
__ Lw(
kScratchReg,
FieldMemOperand(kWasmInstanceRegister,
WasmInstanceObject::kRealStackLimitAddressOffset));
__ Lw(kScratchReg, MemOperand(kScratchReg));
__ Addu(kScratchReg, kScratchReg,
Operand(required_slots * kSystemPointerSize));
__ Branch(&done, uge, sp, Operand(kScratchReg));
}
__ Call(wasm::WasmCode::kWasmStackOverflow, RelocInfo::WASM_STUB_CALL);
// We come from WebAssembly, there are no references for the GC.
ReferenceMap* reference_map = new (zone()) ReferenceMap(zone());
RecordSafepoint(reference_map, Safepoint::kNoLazyDeopt);
if (FLAG_debug_code) {
__ stop();
}
__ bind(&done);
}
}
const int returns = frame()->GetReturnSlotCount();
// Skip callee-saved and return slots, which are pushed below.
......
......@@ -3611,6 +3611,42 @@ void CodeGenerator::AssembleConstructFrame() {
const RegList saves = call_descriptor->CalleeSavedRegisters();
const RegList saves_fpu = call_descriptor->CalleeSavedFPRegisters();
if (required_slots > 0) {
DCHECK(frame_access_state()->has_frame());
if (info()->IsWasm() && required_slots > 128) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
// have enough space on the stack to call the runtime for the stack
// overflow.
Label done;
// If the frame is bigger than the stack, we throw the stack overflow
// exception unconditionally. Thereby we can avoid the integer overflow
// check in the condition code.
if ((required_slots * kSystemPointerSize) < (FLAG_stack_size * 1024)) {
__ Ld(
kScratchReg,
FieldMemOperand(kWasmInstanceRegister,
WasmInstanceObject::kRealStackLimitAddressOffset));
__ Ld(kScratchReg, MemOperand(kScratchReg));
__ Daddu(kScratchReg, kScratchReg,
Operand(required_slots * kSystemPointerSize));
__ Branch(&done, uge, sp, Operand(kScratchReg));
}
__ Call(wasm::WasmCode::kWasmStackOverflow, RelocInfo::WASM_STUB_CALL);
// We come from WebAssembly, there are no references for the GC.
ReferenceMap* reference_map = new (zone()) ReferenceMap(zone());
RecordSafepoint(reference_map, Safepoint::kNoLazyDeopt);
if (FLAG_debug_code) {
__ stop();
}
__ bind(&done);
}
}
const int returns = frame()->GetReturnSlotCount();
// Skip callee-saved and return slots, which are pushed below.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment