Merge train 205: perex 0.1.7 and a lent regex scratch (v0.5.1583) - #10396
Merged
Merged
Conversation
added 6 commits
September 16, 2026 23:37
Three unadopted versions over the pinned 0.1.4: * 0.1.5 — a start-anchored program tries only its first start. Worth a flat ~870-960 instructions per call on the `.test()` probes of #10166, measured against 0.1.4 on the same host. * 0.1.6 — `Search::restart_at`, for a host loop that walks one subject, and `impl ScratchOwner for &mut O`, which lets a host lend scratch instead of giving it up. The next commit takes the second; restart_at is separate work. * 0.1.7 — the `v` flag is complete: string members `[\q{abc|de}]` and the seven properties of strings. Perex reports 48,718 Test262 cases compared with no differences and nothing unsupported. 0.1.7 bumps the program format (HEADER 10 -> 11 words, VERSION 12 -> 13, a new SEQUENCE instruction and a filter section), and older programs are rejected outright. Perry has nothing to migrate: programs exist only as `GcProgram` / `ProgramCell` on the GC heap, and no cache keys on program words — not `.perry-cache`, not the auto-optimize cache, which key on source and objects. `State`, `Frame` and `Phase` are unchanged; `Shape`s header copy grows one
…g one per call #10166's attribution put a third of a short `.test()` in scratch the call never needed to build: `find_near` constructed a `MatchBuffers` per call, a 32-register inline array zeroed and then moved by value into `Search`, which disassembled to `mov $0x150,%edx; call memcpy` — 336 bytes at every call. Nothing in that scratch depends on the subject, and a search initializes its own live state, so perex 0.1.6's `impl ScratchOwner for &mut O` lets one per-thread cell serve every search. The cell keeps whatever frames and undo length an earlier call needed, which removes the other half of the cost: `PERRY_REGEX_DIAG` counted a scratch growth on nearly every search, so each call was rebuffering as well as constructing. In steady state a loop grows nothing and constructs nothing. A search that asks for more than the cell holds grows it for the next call and lets this one run the owned path from the budget it entered on, so a single call charges exactly the work it charges today. Reentrancy is a runtime borrow rather than the compile-time one perex gives a single frame: a nested regex — a replacer callback that matches, or a poll that re-enters — finds the cell borrowed and takes the owned path, so two searches never share slots. The operation's memory limit still sees the slots: the lent path takes a `Charge` for what it lends, exactly as the owner it replaces did. No GC pointer is stored in the cell. INLINE_REGISTERS drops 32 -> 8 for the owned path, which is now only a fallback; the lent cell keeps 32 in LENT_REGISTERS, since it is allocated once per thread rather than moved per call.
`perex_host_failures_release_scratch_and_preserve_consumed_work` used `[a--b]` under `v` as its Unsupported witness, on the note that the union grammar compiled but the set *operators* did not. 0.1.7 implements them, so that arm now compiles successfully and the test failed on its own assertion that the compile errored. The cleanup coverage it was there for is unchanged: compile failures still release scratch and keep the work they charged, exercised by the remaining syntax-error and exhausted-work arms. `[a--b]` becomes a positive case instead — a real difference, matching the `a` at index 1 of "ba" and not the `b` at 0 — so the newly supported grammar is asserted rather than dropped.
check_thread_locals rejects a raw thread_local! in perry-runtime (#7469): the address belongs in this thread's hot cache instead of costing a _tlv_get_addr call on every access. That applies with force here — every search on the thread reads this cell, which is the opposite of what a cold declaration looks like — so it is declared hot, with a const initializer.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThe workspace updates to version ChangesPerex release and runtime scratch
Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant find_near
participant ScratchCell
participant Search
participant MatchBuffers
find_near->>ScratchCell: attempt lent search
ScratchCell->>Search: run search with shared scratch
Search-->>ScratchCell: return match or capacity error
ScratchCell-->>find_near: return Lent::Done or Lent::Fallback
find_near->>MatchBuffers: use owned buffers after fallback
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This train lands #10372 as v0.5.1583. It sits on
872ce07e24and cherry-picks clean.#10166) — takes perex 0.1.7 and stops building a fresh regex scratch on every search. The scratch is now lent from the thread, so a search borrows it instead of allocating one per call.Five source commits, each verified to preserve its patch-id and authorship.
No train repairs
All five source commits are exact patch-id cherry-picks with authorship preserved byte-for-byte (name, email and author date all unchanged). The train adds only the version bump.
Worth naming the fifth one, because it is the gate this change had to satisfy: the lent scratch is a runtime-side cache of a heap pointer, which is a GC root the static checker cannot see. It has to be declared with
perry_thread_local!and carry a verdict inscripts/gc_runtime_root_holders.json, or the holders gate fails. The author's own6b9d09a198does exactly that, and it is in this train.Validation
Validated head
c091bb1807. Five-package release build pinned and hash-verified, and re-verified after the gap run (artifacts_match_pin_after_gap) so nothing rebuilt underneath the fixtures.main's one known runtime failure.--no-raise-vs), the holders gate, and the unrooted-local-shape check againstmain.regex,regexp,unicode— 42 fixture selections, 100% parity on each, snapshot clean. That is the right exposure for this change: it swaps the regex engine version and changes scratch lifetime, so every fixture that compiles a pattern is in scope.Remaining red on the source PR is entirely inherited from
main:gap-suiteshards 3, 4 and 5 (the three long-standing regressions —test_gap_iterator_prototype_next_patch,test_gap_2899_2779_2777_static_helpers,test_gap_disposablestack_2875), benchmark-evidence freshness inlint, the pre-existingrustlsRUSTSEC-2026-0285 advisory, and thepr-gatefan-in over those. #10387 fixes all three gap shards and is the next train.Before merging, the pushed head and unchanged main are checked again. After merging, the rewritten commits are checked for preserved authorship and the main tree must match the validated train exactly.
Summary by CodeRabbit
Performance
.test()andexecoperations.New Features
v-flag support for string properties, string members, and Unicode set operators.Bug Fixes