Skip to content

build: the object cache doesn't key on codegen env vars — PERRY_WRITE_BARRIERS=0 silently does nothing with a warm cache #6394

Description

@proggeramlug

Summary

Perry's object cache keys on source + compiler identity, but not on codegen-affecting environment variables. So a build with such a variable set silently reuses the .o from a build without it — the switch appears to do nothing, and any A/B built on it is vacuous.

Why this is worse than a stale-cache annoyance

CLAUDE.md documents PERRY_WRITE_BARRIERS=0 as a compile-time bisection tool:

PERRY_WRITE_BARRIERS=0/off/false disables codegen-emitted write barriers at compile time … for benchmark/debug bisection

It is read in codegen (crates/perry-codegen/src/expr/write_barrier.rs, codegen/helpers.rs), so it changes emitted IR. But with a warm node_modules/.cache/perry, setting it changes nothing — you get the previously-cached object, with barriers still in. The bisection tool silently lies, and you conclude "barriers aren't the cause" from an experiment that never ran.

This was found the hard way: while validating #6385 (PR #6393), the falsification run — the one meant to prove the new tests can fail — passed. That would have been a worthless green. It only went red after rm -rf node_modules/.cache/perry. A test that passes because the cache served a stale object is indistinguishable from a test that passes because the code is correct.

Repro

perry compile x.ts -o x                      # populates the cache
PERRY_WRITE_BARRIERS=0 perry compile x.ts -o x2   # reuses the cached .o; barriers still emitted

Compare the emitted IR (--trace llvm) for the two — identical.

Affected switches (any env var read during codegen)

(Runtime-only knobs — PERRY_GEN_GC, PERRY_GC_FORCE_EVACUATE, PERRY_GC_DIAG — are unaffected: they are read by the linked runtime at execution time, not baked into the object.)

Fix

Fold the values of all codegen-affecting env vars into the object-cache key (build_cache.rs). Ideally register them in one place so a new switch cannot be added without also entering the key — a CODEGEN_ENV_KEYS: &[&str] array consulted by both the reader and the hasher, so the two cannot drift.

A cheaper interim: have --trace llvm / a warning note when a codegen env var is set and the cache is hit, so the user knows the switch did not take effect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions