Skip to content

Commit 6508440

Browse files
thibaudmichaudV8 LUCI CQ
authored andcommitted
[wasm][jspi] Fix stack unwinding at stack boundary
When an exception is not caught by the current stack and is forwarded to the parent stack, treat it as a return stack-switch: retire the current stack and mark the parent as the new active stack. [email protected],[email protected] Fixed: 363051803 Change-Id: I700dfb1972cfdf4a35e4a0d5d0f5b53cb48b7a9c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5831369 Reviewed-by: Clemens Backes <[email protected]> Commit-Queue: Thibaud Michaud <[email protected]> Reviewed-by: Igor Sheludko <[email protected]> Cr-Commit-Position: refs/heads/main@{#95925}
1 parent dc03a6d commit 6508440

4 files changed

Lines changed: 36 additions & 19 deletions

File tree

src/execution/isolate.cc

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,10 +2232,16 @@ Tagged<Object> Isolate::UnwindAndFindHandler() {
22322232
// We reached the base of the wasm stack. Follow the chain of
22332233
// continuations to find the parent stack and reset the iterator.
22342234
DCHECK(!continuation.is_null());
2235-
continuation = Cast<WasmContinuationObject>(continuation->parent());
22362235
wasm::StackMemory* stack =
22372236
reinterpret_cast<wasm::StackMemory*>(continuation->stack());
2238-
iter.Reset(thread_local_top(), stack);
2237+
RetireWasmStack(stack);
2238+
continuation = Cast<WasmContinuationObject>(continuation->parent());
2239+
wasm::StackMemory* parent =
2240+
reinterpret_cast<wasm::StackMemory*>(continuation->stack());
2241+
parent->jmpbuf()->state = wasm::JumpBuffer::Active;
2242+
roots_table().slot(RootIndex::kActiveContinuation).store(continuation);
2243+
SyncStackLimit();
2244+
iter.Reset(thread_local_top(), parent);
22392245
}
22402246
}
22412247
#endif
@@ -3753,6 +3759,25 @@ void Isolate::UpdateCentralStackInfo() {
37533759
}
37543760
}
37553761

3762+
void Isolate::RetireWasmStack(wasm::StackMemory* stack) {
3763+
stack->jmpbuf()->state = wasm::JumpBuffer::Retired;
3764+
size_t index = stack->index();
3765+
// We can only return from a stack that was still in the global list.
3766+
DCHECK_LT(index, wasm_stacks().size());
3767+
std::unique_ptr<wasm::StackMemory> stack_ptr =
3768+
std::move(wasm_stacks()[index]);
3769+
DCHECK_EQ(stack_ptr.get(), stack);
3770+
if (index != wasm_stacks().size() - 1) {
3771+
wasm_stacks()[index] = std::move(wasm_stacks().back());
3772+
wasm_stacks()[index]->set_index(index);
3773+
}
3774+
wasm_stacks().pop_back();
3775+
for (size_t i = 0; i < wasm_stacks().size(); ++i) {
3776+
SLOW_DCHECK(wasm_stacks()[i]->index() == i);
3777+
}
3778+
stack_pool().Add(std::move(stack_ptr));
3779+
}
3780+
37563781
wasm::WasmOrphanedGlobalHandle* Isolate::NewWasmOrphanedGlobalHandle() {
37573782
return wasm::WasmEngine::NewOrphanedGlobalHandle(&wasm_orphaned_handle_);
37583783
}

src/execution/isolate.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,6 +2205,12 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
22052205
void UpdateCentralStackInfo();
22062206

22072207
void SyncStackLimit();
2208+
2209+
// To be called when returning from {stack}, or when an exception crosses the
2210+
// stack boundary. This updates the {StackMemory} object and the global
2211+
// {wasm_stacks_} list. This does *not* update the ActiveContinuation root and
2212+
// the stack limit.
2213+
void RetireWasmStack(wasm::StackMemory* stack);
22082214
#else
22092215
bool IsOnCentralStack() { return true; }
22102216
#endif

src/wasm/stacks.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,6 @@ Address StackMemory::Shrink() {
113113
void StackMemory::Reset() {
114114
active_segment_ = first_segment_;
115115
size_ = active_segment_->size_;
116-
#if DEBUG
117-
constexpr uint8_t kZapValue = 0xab;
118-
FillWith(kZapValue);
119-
#endif
120116
}
121117

122118
std::unique_ptr<StackMemory> StackPool::GetOrAllocate() {

src/wasm/wasm-external-refs.cc

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -970,19 +970,9 @@ void return_switch(Isolate* isolate, Address raw_continuation) {
970970

971971
Tagged<WasmContinuationObject> continuation =
972972
Cast<WasmContinuationObject>(Tagged<Object>{raw_continuation});
973-
size_t index = reinterpret_cast<StackMemory*>(continuation->stack())->index();
974-
// We can only return from a stack that was still in the global list.
975-
DCHECK_LT(index, isolate->wasm_stacks().size());
976-
std::unique_ptr<StackMemory> stack = std::move(isolate->wasm_stacks()[index]);
977-
if (index != isolate->wasm_stacks().size() - 1) {
978-
isolate->wasm_stacks()[index] = std::move(isolate->wasm_stacks().back());
979-
isolate->wasm_stacks()[index]->set_index(index);
980-
}
981-
isolate->wasm_stacks().pop_back();
982-
for (size_t i = 0; i < isolate->wasm_stacks().size(); ++i) {
983-
SLOW_DCHECK(isolate->wasm_stacks()[i]->index() == i);
984-
}
985-
isolate->stack_pool().Add(std::move(stack));
973+
wasm::StackMemory* stack =
974+
reinterpret_cast<StackMemory*>(continuation->stack());
975+
isolate->RetireWasmStack(stack);
986976
isolate->SyncStackLimit();
987977
}
988978

0 commit comments

Comments
 (0)