Sitelet https://github.com/flutter/flutter/pull/192072
Skip to content

[web] Defer disposal of stale cached paths to FrameArena - #192072

Merged
auto-submit[bot] merged 6 commits into
flutter:masterfrom
mdebbar:fix_flutter_issue_191976
Sep 24, 2026
Merged

auto-submit[bot] merged 6 commits into
flutter:masterfrom
mdebbar:fix_flutter_issue_191976

Conversation

@mdebbar

@mdebbar mdebbar commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

When mutating an EnginePath after building and drawing it in the same frame, _invalidateCachedPath() was prematurely disposing _cachedPath.

In multi-threaded WebAssembly (skwasm), this eager mid-frame deallocation violated the lifecycle contract of FrameArena and caused native allocations to be freed on the main thread while background raster thread operations were deallocating previous display lists in the same linear memory space, leading to heap corruption and RuntimeError: memory access out of bounds in $emscripten_builtin_free.

This change keeps invalidated BackendPath instances in _stalePaths until the end of the frame when FrameArena.collect() runs.

Fixes #191976

Pre-launch Checklist

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Aug 31, 2026
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team labels Aug 31, 2026

@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 defers the disposal of invalidated backend paths in EnginePath by collecting them in a list and disposing them during the collect phase, preventing premature deallocation during concurrent rasterization. A new test is added to verify concurrent path mutation and rasterization. The review feedback suggests optimizing memory overhead by lazily initializing the stale paths list only when a path is invalidated, and updating the collection logic accordingly.

Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/primitives/path.dart
Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/primitives/path.dart Outdated
When mutating an EnginePath after building and drawing it in the same
frame, _invalidateCachedPath() was prematurely disposing _cachedPath.
In multi-threaded WebAssembly (skwasm), this eager mid-frame deallocation
interleaved with background raster thread deallocations, leading to heap
corruption and RuntimeError: memory access out of bounds in $emscripten_builtin_free.

This change keeps invalidated BackendPath instances alive in _stalePaths
until the end of the frame, respecting the FrameArena lifecycle contract.

Fixes flutter#191976
@mdebbar
mdebbar force-pushed the fix_flutter_issue_191976 branch from fd63ba9 to 6183cb0 Compare August 31, 2026 18:43

@harryterkelsen harryterkelsen 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.

LGTM

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

Labels

CICD Run CI/CD 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.

Reproducible wasm-only crash

2 participants