#54234: fix: reject V8 code caches written by a differently patched build
Description of Change
Before: V8 keys JS code caches and serialized wasm modules on its version number alone. Release branches cherry-pick V8 fixes as patches without changing that number, so an app that updated between two releases on the same Chromium roll kept deserializing wasm code written by the previous build. When the cherry-pick renumbered builtins (44.3.0 → 44.4.0, cherry-pick-74a4cfde7e.patch, 55 of the 154 wasm jump-table builtins moved by one), the cached code was relinked against the wrong builtins and every previously tiered-up function trapped (RuntimeError: unreachable) or crashed the renderer until the cache was cleared.
After: a code cache or serialized wasm module is only accepted by a build with the same V8 version, the same patches/v8 contents and the same embedded builtins blob; anything else is rejected and recompiled from source.
patches/v8: newv8_version_hash_salt/v8_version_hash_salt_filesGN args mixed intoVersion::Hash()(JS code cache,CachedDataVersionTag(), wasm header). The files variant is fingerprinted atgn gentime bygni/version_hash_salt.gniwith the files as regeneration dependencies, and the salt reachesversion.ccthrough a gen-time header so a change recompiles one file. The serialized wasm module header additionally carries the embedded blob data+code hashes. Both halves are upstreamable.build/args/all.gn:v8_version_hash_salt_files=patches/v8/.patchesplus every patch it lists.patches/chromium/build_allow_electron_to_use_exec_script.patch: allowlist the new gni.
Verified on linux-x64 with a page that instantiateStreamings a module over http and tiers it up:
| cache written by | run with | result |
|---|---|---|
| build A | build A | moduleCacheHit, reused |
| build A | build A + one-line change to a patches/v8 description |
moduleCacheInvalid, recompiled, runs clean (11 objects rebuilt) |
| build B | build B + one extra Torque builtin, patches untouched | moduleCacheInvalid, recompiled, runs clean |
| 44.3.0 (stock) | 44.4.0 (stock) | RuntimeError: unreachable (the bug) |
Checklist
- I have built and tested this change
- I have filled out the PR description
- I have reviewed and verified the changes
Release Notes
Notes: Fixed WebAssembly modules loaded from the code cache crashing or throwing RuntimeError: unreachable after updating between certain patch releases.
Backports
Semver Impact
Semantic Versioning helps users understand the impact of updates:
- Major (X.y.z): Breaking changes that may require code modifications
- Minor (x.Y.z): New features that maintain backward compatibility
- Patch (x.y.Z): Bug fixes that don't change the API
- None: Changes that don't affect using facing parts of Electron