@@ -338,6 +338,21 @@ class ActivationsFinder : public ThreadVisitor {
338
338
// for the trampoline to the deoptimizer call respective to each code, and use
339
339
// it to replace the current pc on the stack.
340
340
void VisitThread (Isolate* isolate, ThreadLocalTop* top) override {
341
+ #if V8_ENABLE_WEBASSEMBLY
342
+ // Also visit the ancestors of the active stack for wasm stack switching.
343
+ // We don't need to visit suspended stacks at the moment, because 1) they
344
+ // only contain wasm frames and 2) wasm does not do lazy deopt. Revisit this
345
+ // if one of these assumptions changes.
346
+ Tagged<WasmContinuationObject> continuation;
347
+ if (top == isolate->thread_local_top ()) {
348
+ Tagged<Object> maybe_continuation =
349
+ isolate->root (RootIndex::kActiveContinuation );
350
+ if (!IsUndefined (maybe_continuation)) {
351
+ continuation = Cast<WasmContinuationObject>(maybe_continuation);
352
+ }
353
+ }
354
+ #endif
355
+
341
356
for (StackFrameIterator it (isolate, top); !it.done (); it.Advance ()) {
342
357
if (it.frame ()->is_optimized ()) {
343
358
Tagged<GcSafeCode> code = it.frame ()->GcSafeLookupCode ();
@@ -371,6 +386,19 @@ class ActivationsFinder : public ThreadVisitor {
371
386
}
372
387
}
373
388
}
389
+
390
+ #if V8_ENABLE_WEBASSEMBLY
391
+ // We reached the base of the wasm stack. Follow the chain of
392
+ // continuations to find the parent stack and reset the iterator.
393
+ if (it.frame ()->type () == StackFrame::STACK_SWITCH) {
394
+ CHECK_EQ (top, isolate->thread_local_top ());
395
+ DCHECK (!continuation.is_null ());
396
+ continuation = Cast<WasmContinuationObject>(continuation->parent ());
397
+ wasm::StackMemory* parent =
398
+ reinterpret_cast <wasm::StackMemory*>(continuation->stack ());
399
+ it.Reset (top, parent);
400
+ }
401
+ #endif
374
402
}
375
403
}
376
404
0 commit comments