[stable] [web] Use thread local strike caches in skwasm (#190048) by SynSzakala · Pull Request #192115 · flutter/flutter · GitHub
Skip to content

[stable] [web] Use thread local strike caches in skwasm (#190048) - #192115

Closed
SynSzakala wants to merge 1 commit into
flutter:flutter-3.47-candidate.0from
SynSzakala:cp-stable-skwasm-thread-local-strike-cache
Closed

[stable] [web] Use thread local strike caches in skwasm (#190048)#192115
SynSzakala wants to merge 1 commit into
flutter:flutter-3.47-candidate.0from
SynSzakala:cp-stable-skwasm-thread-local-strike-cache

Conversation

@SynSzakala

Copy link
Copy Markdown

Cherry-pick of #190048 (d3ac5cdfb70971a1b28ca67240860675a6b3598c) onto flutter-3.47-candidate.0. It applies cleanly — all four modified files are byte-identical between the fix's parent and the candidate branch, and the added test does not exist on either, so no conflict resolution was involved.

Issue: #190039

Impacted Users

Anyone shipping a flutter build web --wasm app served cross-origin isolated — via COOP/COEP or Document-Isolation-Policy — which is what selects multi-threaded skwasm. This hits end users of those apps, not only developers.

Impact Description

A silent, unrecoverable freeze of the running app.

Multi-threaded skwasm is built with -sWASM_WORKERS but without -pthread, so it links the single-threaded emscripten system libraries where mutexes are no-ops. Main-thread text layout and the raster worker then share the global SkStrikeCache and corrupt the heap under text churn. It surfaces either as RuntimeError: memory access out of bounds from skwasm.wasm, or as nothing at all in the console; afterwards the page never runs JS again — requestAnimationFrame stops, and a core stays pinned.

Field data from our production web app (Flutter 3.44.7, wasm, thousands of daily users), in case it is useful for prioritisation:

  • We captured a Chrome DevTools profile of a live freeze. The main thread's stack is RenderParagraph.performLayoutTextPainter._createParagraph → engine renderer.dartskwasm.wasm → a busy-spin on emscripten_get_now, held for the full 7.7 s remaining in the trace. The skwasm render worker sits 100% idle beside it. The compositor keeps issuing BeginFrame at 60/s with no main frame ever committing.
  • RuntimeError: memory access out of bounds with a skwasm culprit went from 10 events across all prior releases to 111 in the two weeks after we enabled cross-origin isolation — the only change that turned multi-threaded skwasm on.
  • The innermost frames of those crash stacks and of the frozen profile are the same skwasm.wasm functions, i.e. the trap and the spin are the two presentations of one defect, exactly as described in [web][skwasm] Wasm heap corruption under concurrent text layout and rasterization with multi-threaded skwasm; page then spins at 100% CPU #190039.

Workaround

Yes: forceSingleThreadedSkwasm: true, or stop serving the app cross-origin isolated. Both give up multi-threaded rendering altogether, which is the feature being paid for. We have taken the second option in production.

Risk

Low. The change sets a Skia flag from a constructor in surface.cc so each thread gets its own strike cache. There is no API or behaviour change beyond removing the shared mutable state.

Test Coverage

Yes. The upstream PR adds engine/src/flutter/lib/web_ui/test/skwasm/concurrent_text_layout_raster_test.dart, which is included in this cherry-pick.

Validation Steps

  1. Build a wasm app that lays out fresh multi-span paragraphs every frame while animating — the reproduction in [web][skwasm] Wasm heap corruption under concurrent text layout and rasterization with multi-threaded skwasm; page then spins at 100% CPU #190039 does this.
  2. Serve build/web cross-origin isolated so skwasm picks multi-threaded mode.
  3. Open it in Chrome.

Before: the tab freezes within seconds (3–30 s in the reporter's runs). After: the animation keeps running.


Two notes for the reviewer:

This is not a regression introduced in 3.47. The defect has been present since multi-threaded skwasm shipped, so it sits outside the strict "regression from the previous release" wording of the cherry-pick process. I am requesting it anyway because the failure mode is a silent production freeze with no error surface for most users, the fix is already on master and in beta 3.48, and without a cherry-pick affected apps stay on the single-threaded fallback until 3.50 lands — roughly three months. Entirely happy for this to be closed if the release team would rather it ride the normal train.

Why this commit and not #191014. That follow-up swaps the experimental Skia flag for the officially supported one, and depends on a newer Skia roll than 3.47 carries, so this cherry-pick keeps the original form.

Cherry-pick of d3ac5cd onto flutter-3.47-candidate.0. Applies cleanly; no conflict resolution was needed.

Fixes the multi-threaded skwasm heap corruption tracked in flutter#190039.
@flutter-dashboard

Copy link
Copy Markdown

@github-actions github-actions Bot added a: text input Entering text in a text field or keyboard related problems engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team labels Sep 1, 2026
@SynSzakala

Copy link
Copy Markdown
Author

I don't have permission to apply labels — could someone from the release team add cp: review so this enters the cherry-pick queue? Target branch is flutter-3.47-candidate.0, the current stable candidate per bin/internal/release-candidate-branch.version on stable.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new test for concurrent text layout and rasterization under Skwasm to ensure heap stability. It also enables thread-local strike caches experimentally, refactors surface initialization to allocate the context lost callback ID on the main thread, and implements asynchronous dispatching of resource cache limit updates from the main thread to the worker thread. There are no review comments, so no feedback is provided.

@SynSzakala SynSzakala closed this Sep 1, 2026
@SynSzakala
SynSzakala deleted the cp-stable-skwasm-thread-local-strike-cache branch September 1, 2026 16:04
@SynSzakala

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant