Skip to content

raw_handle_debt --no-raise-vs treats a pure file split as new debt, so a debt-carrying file cannot be split for the 2000-line cap #10583

Description

@proggeramlug

scripts/raw_handle_debt.py --no-raise-vs <base> compares recorded ceilings per path, and treats any path not present at the merge base as a raise:

crates/perry-runtime/src/object/native_module/vtable_access.rs: ceiling raised to 4 (was not listed at the merge base)

That is correct for new debt. It is wrong for a pure relocation, and the 2000-line file cap forces relocations regularly.

Concretely, while landing #10565 (five lines into object/native_module.rs, which sat at exactly 2000) the file had to be split. Moving the three NativeModuleVtable field-access impls out took their four recorded raw-handle sites with them. The ledger then needs native_module.rs's 4 line deleted (the bare run demands it: "ceiling of 4 matches nothing — the module is clean (or gone). DELETE its line") and the new module listed at 4. The bare run passes. --no-raise-vs then fails, because the new path was not listed at the base — even though:

  • total debt is unchanged (906 (baseline 906)), and
  • the moved bodies are byte-identical.

So the two required invocations of this gate disagree about the same tree, and the only ways out are to pay down debt in code you are merely relocating, or to pick a different split. I picked a different split — the CJS default-export group, which happens to carry zero sites — but that is luck, not a strategy: it only worked because all four of this file's sites were in one block. A file whose debt is spread across it cannot be split at all without first paying the debt down.

Suggested fix: let the head ledger declare a relocation, e.g.

4 crates/perry-runtime/src/object/native_module/vtable_access.rs  # moved-from: object/native_module.rs

and have --no-raise-vs credit moved-from's base ceiling against the new path, requiring the source path to be absent (or reduced by at least that much) at head. The total check already guards the thing that matters, so this stays monotone: the sum cannot rise, and a relocation cannot be used to launder new sites, because the source must actually give up the count.

A cheaper interim option is a --moved <old> <new> flag the splitting commit passes, but the in-ledger form is self-documenting and survives in the tree.

Found while landing merge train 216; the split that worked around it is object/native_module/cjs_default.rs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions