◐ Shell
clean mode source ↗

Optimize startup time when user site is disabled. by methane · Pull Request #131 · python/cpython

SonicField added a commit to SonicField/cpython that referenced this pull request

@SonicField

…ntinel

Per docs/w-i3-runtime-assert-spec.md (theologian 21:57:02Z, supervisor
22:10:02Z, librarian 22:05:19Z framework guidance). Closes pythia
python#128 / python#131 python#1 named risk: I3 invariant (BasicBlock::id is allocation-
monotonic AND never mutated post-allocation) is grep-only, not
runtime-asserted.

Phase B B-gamma's PhxBcBlockArray (Tier 8 SECOND-PILOT, push 40
4145fe3) indexes by BasicBlock::id. A future HIR pass that
renumbers ids (SSA-destruction-style cache-locality renumbering,
peephole block-splitter, speculative-inlining clone) would silently
corrupt the dense-array lookup; I2 read-site check catches out-of-
range, NOT stale-mapping-correct-range.

(IV) CI grep gate — scripts/check_i3_invariant.sh + Step 1h wire:
- Detects "->id =", ".id =", set_id(/setId( patterns in Python/jit/hir/.
- Allow-list excludes legitimate non-BasicBlock matches:
  * HirLoadAttrSpecial::id (void* attribute identifier, different
    class)
  * next_register_id_, cache_id_ (different fields, trailing
    underscore)
  * test_*.c, hir_instr_c_verify.cpp (read-path testing, per W44
    ALLOW_LIST precedent)
- Falsification-tested: synthetic patch adding "block->id = 42;"
  to Python/jit/hir/synth_i3_violation.cpp triggers GATE FAIL EXIT=1
  under --strict; removing the patch returns to GATE PASS EXIT=0.
- Wired as Step 1h in scripts/gate_phoenix.sh per librarian 22:05:19Z
  framework guidance, mirroring Steps 1e/1g delegation shape (capture
  OUTPUT, tee to RESULTS_FILE, GATE_PASS=0 + FAILURES on nonzero).

(III) JIT_DCHECK pydebug sentinel — PhxBcBlockEntry.sentinel_id:
- Adds int sentinel_id field under #ifdef Py_DEBUG to PhxBcBlockEntry
  (zero release-build cost; pydebug entry size 8 -> 12 bytes).
- Insert sets sentinel_id = block_id at insert time.
- Lookup verifies sentinel_id == block_id via JIT_DCHECK_C; mismatch
  fires JIT_CHECK_C abort with diagnostic indicating either a
  post-allocation id mutation OR inserter/reader index disagreement.
- catches the (IV) miss-class: id mutation via member function /
  indirect pointer write that grep doesn't pattern-match.

Combined cost: zero release runtime; ~45min implementation. (I)
sentinel-always and (II) generation-counter REJECTED per spec §3 as
reverse perf trade without strong evidence the always-on detection
is required vs (IV)+(III) catching at commit + pydebug.

Build implications: Py_DEBUG-conditional layout change to
PhxBcBlockEntry. Per JIT Header Change Protocol (CLAUDE.md), requires
full distclean rebuild; testkeeper to verify both release (sentinel
field absent, struct == 8 bytes) and pydebug (sentinel field present,
struct == 12 bytes, JIT_DCHECK_C does not fire on normal workload).
ARM64 verification via standard ARM64 retroactive-debt path once
devgpu004 SSH-2FA infra restored.

Auth: theologian spec 21:57:02Z + supervisor CONCUR 21:57:20Z +
22:10:02Z; librarian framework guidance 22:05:19Z (Step 1h shape
mirroring 1e/1g, scripts/check_i3_invariant.sh --strict).