# JIT assumption survives mutation without deopt

Optimized code caching shape, escape state or register type that a mutation path fails to invalidate

_Area: Memory corruption and native code. Seen in 2 disclosed reports; one confirmed bounty: $250,000; latest 2026-10-13. Updated 2026-11-02._

## How it works
An optimizing compiler (or code generator) records a fact about a value — its object shape, its escape/materialization state, its register or type — and emits code that relies on that fact staying true. A separate mutation path changes the underlying state without triggering the deopt or invalidation that would discard the optimized code. The stale assumption then lets optimized code read or write a value as a type or location it no longer is. The invariant that breaks: every mutation of state an optimizer observed must either deopt the dependent code or be invisible to it.

## Where it shows up
- Deopt literals or constants holding mutable heap objects (e.g. HeapNumbers) that get reconstructed and shared [E1](https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md)
- Escape analysis that dematerializes an object but keeps a sub-allocation (backing store, FixedArray) alive [E3](https://bugbountylibrary.com/r/p0%3ACVE-2022-1364.md)
- Paths that materialize the same activation more than once without deoptimizing (stack capture, `Error.prepareStackTrace`) [E3](https://bugbountylibrary.com/r/p0%3ACVE-2022-1364.md)
- Codegen cases that leave the value stack unbalanced, so later opcodes consume a neighboring register [E2](https://bugbountylibrary.com/r/h1%3A226200.md)
- Downstream consumers treating a sandbox "detached"/"frozen" state as immutable [E1](https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md)

## How to review
For each cached fact, find every writer of the underlying state and confirm each one deopts or invalidates. Check that reconstructed/materialized objects never share a mutable box or backing store across instances. In code generators, verify every case leaves the value stack balanced (a missing push is a silent type confusion). Treat "detached", "transferred" or "frozen" as a promise the sandbox does not enforce — confirm the consumer re-checks rather than assumes.

## How finders spotted it
- Reasoned about obligations a sandbox threat model imposes on downstream code, then hunted code assuming transferred buffers were immutable [E1](https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md)
- Noticed a retry path inferred source geometry from a failed read, an assumption broken by a bypass flag [E1](https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md)
- Read `gen_assignment`, saw the default case `return;` skip the final `push(val)`, then tested which register a later opcode used [E2](https://bugbountylibrary.com/r/h1%3A226200.md)
- Traced an in-the-wild sample to escape-analysis/materialization interaction; noted it as a variant of an earlier CVE or findable by differential fuzzing [E3](https://bugbountylibrary.com/r/p0%3ACVE-2022-1364.md)

## Variants seen
- Mutable HeapNumber stored as deopt literal, shared across reconstructed objects [E1](https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md)
- Dematerialized ArgumentsObject keeping its backing store, materialized twice [E3](https://bugbountylibrary.com/r/p0%3ACVE-2022-1364.md)
- Codegen early-return leaving a stale register for a splat opcode [E2](https://bugbountylibrary.com/r/h1%3A226200.md)

## Impact and severity
Each gave a memory-corruption primitive: a shared mutable box and a hole leak chained to arbitrary read/write [E1](https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md)[E3](https://bugbountylibrary.com/r/p0%3ACVE-2022-1364.md); a write-what-where chained with string corruption to code execution [E2](https://bugbountylibrary.com/r/h1%3A226200.md). Severity rose with chaining across components — V8 cage, renderer sandbox, and a privileged handler — reaching unsandboxed code execution [E1](https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md). Median bounty $250k reflects full-chain reach [E1](https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md).

## Seen in real software
Open-source packages and projects, and products, where this pattern was found. If the target runs one, compare the version it runs with the fix.
- **Google Chrome** (V8 JavaScript engine) 100.0.4896.79 and previous, fixed in 100.0.4896.127: CVE-2022-1364: Inconsistent Object Materialization in V8 (CVE-2022-1364). Report: https://bugbountylibrary.com/r/p0%3ACVE-2022-1364.md

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Axbow-com-labs-research-zero-to-calc-in-six-days-inside-xbow-chrome-full-chain.md
- E2: https://bugbountylibrary.com/r/h1%3A226200.md
- E3: https://bugbountylibrary.com/r/p0%3ACVE-2022-1364.md
