Commit c0ded6c8 authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm][interpreter] Reload after caught StackOverflow

If a StackOverflow is caught, reload the pc and the limit from the
catching frame, not from the target.

R=clemensb@chromium.org

Bug: chromium:1180339
Change-Id: I41bf94e6c7525106e990306913e446f2c4269df1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2710436Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72891}
parent 24fa74e7
...@@ -1567,15 +1567,11 @@ class WasmInterpreterInternals { ...@@ -1567,15 +1567,11 @@ class WasmInterpreterInternals {
// Returns true if the call was successful, false if the stack check failed // Returns true if the call was successful, false if the stack check failed
// and the stack was fully unwound. // and the stack was fully unwound.
bool DoCall(Decoder* decoder, InterpreterCode* target, pc_t* pc, bool DoCall(Decoder* decoder, InterpreterCode** target, pc_t* pc,
pc_t* limit) V8_WARN_UNUSED_RESULT { pc_t* limit) V8_WARN_UNUSED_RESULT {
frames_.back().pc = *pc; frames_.back().pc = *pc;
PushFrame(target); PushFrame(*target);
if (!DoStackCheck()) return false; return DoStackCheck(decoder, target, pc, limit);
*pc = frames_.back().pc;
*limit = target->end - target->start;
decoder->Reset(target->start, target->end);
return true;
} }
// Returns true if the tail call was successful, false if the stack check // Returns true if the tail call was successful, false if the stack check
...@@ -3155,7 +3151,8 @@ class WasmInterpreterInternals { ...@@ -3155,7 +3151,8 @@ class WasmInterpreterInternals {
// Returns true if execution can continue, false if the stack was fully // Returns true if execution can continue, false if the stack was fully
// unwound. Do call this function immediately *after* pushing a new frame. The // unwound. Do call this function immediately *after* pushing a new frame. The
// pc of the top frame will be reset to 0 if the stack check fails. // pc of the top frame will be reset to 0 if the stack check fails.
bool DoStackCheck() V8_WARN_UNUSED_RESULT { bool DoStackCheck(Decoder* decoder, InterpreterCode** target, pc_t* pc,
pc_t* limit) V8_WARN_UNUSED_RESULT {
// The goal of this stack check is not to prevent actual stack overflows, // The goal of this stack check is not to prevent actual stack overflows,
// but to simulate stack overflows during the execution of compiled code. // but to simulate stack overflows during the execution of compiled code.
// That is why this function uses FLAG_stack_size, even though the value // That is why this function uses FLAG_stack_size, even though the value
...@@ -3165,13 +3162,20 @@ class WasmInterpreterInternals { ...@@ -3165,13 +3162,20 @@ class WasmInterpreterInternals {
const size_t current_stack_size = (sp_ - stack_.get()) * sizeof(*sp_) + const size_t current_stack_size = (sp_ - stack_.get()) * sizeof(*sp_) +
frames_.size() * sizeof(frames_[0]); frames_.size() * sizeof(frames_[0]);
if (V8_LIKELY(current_stack_size <= stack_size_limit)) { if (V8_LIKELY(current_stack_size <= stack_size_limit)) {
*pc = frames_.back().pc;
*limit = (*target)->end - (*target)->start;
decoder->Reset((*target)->start, (*target)->end);
return true; return true;
} }
// The pc of the top frame is initialized to the first instruction. We reset // The pc of the top frame is initialized to the first instruction. We reset
// it to 0 here such that we report the same position as in compiled code. // it to 0 here such that we report the same position as in compiled code.
frames_.back().pc = 0; frames_.back().pc = 0;
isolate_->StackOverflow(); isolate_->StackOverflow();
return HandleException(isolate_) == WasmInterpreter::HANDLED; if (HandleException(isolate_) == WasmInterpreter::HANDLED) {
ReloadFromFrameOnException(decoder, target, pc, limit);
return true;
}
return false;
} }
void EncodeI32ExceptionValue(Handle<FixedArray> encoded_values, void EncodeI32ExceptionValue(Handle<FixedArray> encoded_values,
...@@ -3668,7 +3672,7 @@ class WasmInterpreterInternals { ...@@ -3668,7 +3672,7 @@ class WasmInterpreterInternals {
InterpreterCode* target = codemap_.GetCode(imm.index); InterpreterCode* target = codemap_.GetCode(imm.index);
CHECK(!target->function->imported); CHECK(!target->function->imported);
// Execute an internal call. // Execute an internal call.
if (!DoCall(&decoder, target, &pc, &limit)) return; if (!DoCall(&decoder, &target, &pc, &limit)) return;
code = target; code = target;
continue; // Do not bump pc. continue; // Do not bump pc.
} break; } break;
...@@ -3683,7 +3687,7 @@ class WasmInterpreterInternals { ...@@ -3683,7 +3687,7 @@ class WasmInterpreterInternals {
switch (result.type) { switch (result.type) {
case CallResult::INTERNAL: case CallResult::INTERNAL:
// The import is a function of this instance. Call it directly. // The import is a function of this instance. Call it directly.
if (!DoCall(&decoder, result.interpreter_code, &pc, &limit)) if (!DoCall(&decoder, &result.interpreter_code, &pc, &limit))
return; return;
code = result.interpreter_code; code = result.interpreter_code;
continue; // Do not bump pc. continue; // Do not bump pc.
......
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