MarshallOfSound

#54234: fix: reject V8 code caches written by a differently patched build

Merged
Created: Sep 23, 2026, 1:11:55 PM
Merged: Sep 23, 2026, 2:50:07 PM
9 comments
Target: main

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: new v8_version_hash_salt / v8_version_hash_salt_files GN args mixed into Version::Hash() (JS code cache, CachedDataVersionTag(), wasm header). The files variant is fingerprinted at gn gen time by gni/version_hash_salt.gni with the files as regeneration dependencies, and the salt reaches version.cc through 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/.patches plus 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

Release Notes

Notes: Fixed WebAssembly modules loaded from the code cache crashing or throwing RuntimeError: unreachable after updating between certain patch releases.

Backports

42-x-y
Merged
PR Number
#54239
Merged At
Sep 23, 2026, 4:40:41 PM
Released In
Not yet
Release Date
Not yet
43-x-y
Merged
PR Number
#54238
Merged At
Sep 23, 2026, 4:50:48 PM
Released In
Not yet
Release Date
Not yet
44-x-y
Merged
PR Number
#54246
Merged At
Sep 23, 2026, 4:31:24 PM
Released In
Not yet
Release Date
Not yet
45-x-y
Merged
PR Number
#54237
Merged At
Sep 23, 2026, 6:49:01 PM
Released In
Not yet
Release Date
Not yet

Semver Impact

Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.

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