Skip to content

Core runtime onto the slot API (#1665 arm D B1) - #1706

Merged
InauguralPhysicist merged 1 commit into
mainfrom
arm-d-B1
Oct 10, 2026
Merged

InauguralPhysicist merged 1 commit into
mainfrom
arm-d-B1

Conversation

@InauguralPhysicist

Copy link
Copy Markdown
Collaborator

Part of #1665: batch B1 of the arm D step-2 design. Storage stays Value**.

What it changes

  • eigenscript.h, eigenscript.c and trace.c leave the old borrow API and join tools/container_migrated_files.txt. The gate now forbids the old API in them: files=3 violations=0.
  • eigs_bool_gate moves below the container.h include and tests list_elem_type. Its allowlist row is removed: container-access: examined=25 allowed=25.
  • The typed number readers (eigs_list_num, eigs_elem_num, eigs_opt_num) are slot-native, which takes their 129+ callers allocation-free after the flip.
  • Walkers migrated:
    • ent_child / compute_entropy_impl;
    • free_value and chan_clone_rec;
    • values_equal_impl and value_to_string;
    • write_value_ptr_full;
    • eigs_arg_has_bool's nested scan.
  • The GC edge rows for list items and dict values walk only pointer slots, and clear by take plus slot_decref.
  • Seven exempt shape-contract hashes re-pinned. Each builtin's helper closure includes a mechanically rewritten core helper; no policy changed.

Gates

  • Builder (Codex Cloud):

    check result
    release suite 4205/4205
    slot-rehearsal suite 4206/4206
    jit-smoke pass
    jit_diff 256 programs pass
    trace-corpus tape bytes identical to B0
    bench_dmg_shape Ir +0.0051% (tripwire ±1%)
    freestanding-check, werror_switch_check pass
  • Local, on main with Stale-read detectors for the surviving pools: ASan poisoning + make jit-checked (#1665) #1705: the build passes with no warnings, and the container, num-read, shape-contract and changelog gates pass.

  • Full ASan: didn't finish within the builder's window, so CI's ASan shards are the leak gate for this PR.

Left for later batches

eigs_json_encode_value, desc_isolate_const and sandbox_value_has_callable live in builtins.c and move with B3/B4.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KC99CmwatKssQYggkBCgwF

Batch B1 of the arm D step-2 design. Storage stays Value**.

- eigenscript.h / eigenscript.c / trace.c leave the legacy borrow API and
  join tools/container_migrated_files.txt.
- eigs_bool_gate moves below the container.h include and tests
  list_elem_type (its container_access allowlist row is removed).
- The typed number readers (eigs_list_num / eigs_elem_num /
  eigs_opt_num) are slot-native.
- Walkers migrated: ent_child / compute_entropy_impl, free_value,
  chan_clone_rec, values_equal_impl, value_to_string,
  write_value_ptr_full, eigs_arg_has_bool's nested scan.
- GC edge rows for list items and dict values walk slot_is_ptr /
  slot_as_ptr and clear by take + slot_decref (edge count snapshotted).
- Storage alloc/grow use sizeof(*storage).
- Re-pinned 7 exempt shape hashes (helper closure includes a rewritten
  core helper; no policy change); num_read allowlist updated.

Builder gates (Codex Cloud): release 4205/4205, slot-rehearsal
4206/4206, jit-smoke, jit_diff (256 programs), trace-corpus tape bytes
identical to B0, bench_dmg_shape Ir +0.0051%, freestanding-check,
werror_switch_check. Full ASan did not finish in the builder's window;
CI's ASan shards are the leak gate.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC99CmwatKssQYggkBCgwF
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-10T16:40:59.786211Z 8255661 PR opened
🔒 Security Review ⚠️ Failed 2026-10-10T16:51:52.598733Z 8255661 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@codspeed

codspeed Bot commented Oct 10, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 13 untouched benchmarks


Comparing arm-d-B1 (8255661) with main (7b1a902)

Open in CodSpeed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82556611da

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/eigenscript.c
Comment on lines 1661 to +1662
for (int i = 0; i < v->data.list.count; i++)
val_decref(list_get_borrow(v, i));
if (list_values_storage(v))
free(list_values_storage(v));
slot_decref(list_slot(v, i));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Release backing number boxes when destroying containers

When EIGS_SLOT_REHEARSAL is enabled, list_slot converts a stored VAL_NUM * into an immediate slot, so slot_decref is a no-op and the backing Value remains at refcount 1. Consequently, destroying numeric lists or dictionaries leaks every numeric child; the same borrowed-slot decref pattern in dict_set_hashed_raw and dict_remove also leaks replaced or removed numbers. These paths need to release the raw backing box, for example through the take helpers, before decrefing the logical slot.

Useful? React with 👍 / 👎.

Comment thread src/eigenscript.c
Comment on lines 1821 to +1822
int eigs_opt_num(const Value *v, double *out, const char *who) {
if (!v || v->type == VAL_NULL) return 0;
if (v->type == VAL_NUM) { *out = VAL_NUM_RAW(v); return 1; }
eigs_num_arg(v, who);
return 0;
return eigs_slot_opt_num(eigs_container_slot((Value *)v), out, who);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the NULL case in eigs_opt_num

eigs_opt_num previously treated v == NULL as an absent optional value, as its header contract specifies. The new wrapper encodes NULL as a heap-tagged slot with a zero payload, after which eigs_slot_opt_num evaluates slot_as_ptr(s)->type and segfaults; any C caller using the documented absent-value case now crashes instead of retaining its default. Keep the explicit NULL guard or translate NULL to slot_null().

Useful? React with 👍 / 👎.

Comment thread src/eigenscript.c
for (int i = 0; i < n; i++) {
Value *ce = chan_clone_rec(list_get_borrow(v, i), depth + 1);
EIGS_VIEW(child_view);
Value *ce = chan_clone_rec(list_get_view(v, i, &child_view), depth + 1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Clone numeric views before applying the channel depth fallback

When a channel payload has a numeric element directly below a container at depth 64, list_get_view creates a stack-backed numeric facade and passes it to chan_clone_rec at depth 65. The function's earlier depth fallback then increfs and returns that facade before reaching the VAL_NUM clone case, so the caller stores a stack pointer and the cleanup guard aborts with numeric view refcount moved; a chain of 65 nested lists ending in a number reproduces this through val_clone_for_send. Handle numeric views before the depth fallback, or otherwise ensure the fallback never retains a facade.

Useful? React with 👍 / 👎.

Comment thread src/eigenscript.c
Comment on lines 1673 to +1675
for (int i = 0; i < v->data.dict.count; i++) {
/* Keys have table/private-node ownership; do not free individually. */
val_decref(dict_value_get_borrow(v, i));
slot_decref(dict_value_slot(v, i));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Encode null and boolean container values as immediate slots

eigs_container_slot leaves stored VAL_NULL and VAL_BOOL singletons encoded as heap slots, so the newly introduced slot_decref calls bypass val_decref's guard that makes those singletons immortal. Appending a singleton does not increase its refcount, but destroying each containing list or dictionary now subtracts one, as do the migrated replacement, removal, and GC paths; after enough drops, free_value attempts to free a static singleton. Encode these values as slot_null()/slot_from_bool() or preserve the immortal-type check in slot refcounting.

Useful? React with 👍 / 👎.

@InauguralPhysicist
InauguralPhysicist added this pull request to the merge queue Oct 10, 2026
Merged via the queue into main with commit e6ea6da Oct 10, 2026
32 checks passed
@InauguralPhysicist
InauguralPhysicist deleted the arm-d-B1 branch October 10, 2026 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants