Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,20 @@ regex = "1.12"
aho-corasick = "1.1"
memchr = "2"
# The single regular-expression engine, through crates/perry-perex.
perex = "0.1.9"
# 0.1.11 carries PerryTS/perex#3 (package-shaped repeats and classes leave the
# per-character phase loop; release commit 80845f5310, tag v0.1.11). It is
# younger than the 7-day `global-min-publish-age` soak (.cargo/config.toml),
# so Cargo.lock was resolved once with CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow
# under an owner-approved one-time publish-age override (2026-09-28), for this
# version only; the window itself is unchanged. No public API change from
# 0.1.10. Published 2026-09-27T21:13:35Z, sha256
# 4cacad0d8fd77338345abb71e4f8372ce93bf0e9205d845940f8e789b3fc98a8 — the
# checksum Cargo.lock records, verified against
# https://crates.io/api/v1/crates/perex/0.1.11. As with turnloop above, the
# opt-out is a committed, reviewable change, never a silent one, and the lock
# pins the exact artifact. The override lapses on its own on 2026-10-04, when
# 0.1.11 clears the window.
perex = "0.1.11"
# turnloop P0/P1: the per-agent event-loop wait driver and, since P1, Perry's
# stream sockets (docs/turnloop/p0-report.md, crates/perry-runtime/src/turnloop_net).
# 0.1.0-alpha.3 switched turnloop's own dependency requirements from exact pins
Expand Down
5 changes: 5 additions & 0 deletions changelog.d/11548-perex-0111-package-regex-shapes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Performance

- The regex engine moves from perex 0.1.9 to 0.1.11. 0.1.11 carries PerryTS/perex#3, which takes package-shaped repeats and character classes out of the matcher's per-character loop. Measured with `perf stat -e instructions:u` (two-N differential) on perrymaster against `main`: uuid's `validate` regex −65.2% per call, jws's `JWS_REGEX.test` −84.3%, `/^\d+$/.test` −5.4%, and on the package workloads jsonwebtoken/decode −61.1%, uuid/v4 −47.9%, uuid/v7 −34.4%, nanoid/generate −30.4% and uuid/v5_parse −28.4%. Every output is byte-identical to Node 26.5.1, and peak RSS does not move beyond run-to-run noise (#10166).
- perex 0.1.10's `Search::run` fails with `RunError { error, remaining_work, buffers }`. Perry's two search sites now record the work a failed run left instead of keeping the budget they started with. Nothing observes this today, because the budget is `usize::MAX` on these paths.
- perex 0.1.11 is younger than the 7-day cargo `min-publish-age` soak. The owner approved a one-time override for this version on 2026-09-28. `Cargo.lock` was resolved once with `CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow`, and the `Cargo.toml` comment records the approval, the publish time and the sha256 the lock pins, checked against the crates.io API. The soak window is unchanged.
40 changes: 16 additions & 24 deletions crates/perry-runtime/src/regex/perex_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,18 +422,14 @@ fn find_near_lent<'mem, S: ImmutableSubject<Error = OwnerError>>(
// Both views are acquired once for the quantum that decides nearly
// every per-call search; a `Search` is built and moved only if this
// one pauses or asks for more scratch.
// On an error that is not a capacity request -- WorkLimit,
// InvalidProgram, ChangedResources, Cancelled -- `run` returns Err and
// drops the scratch and the remaining budget, where `new` + `advance`
// left a Search to read `remaining_work()` from. So `*budget` keeps its
// entry value and under-counts what the failed call spent. WORK is
// usize::MAX on every path here, so nothing observes it today; if a
// finite execution budget is ever reintroduced (see #10164/#10165),
// this stops being free and wants the engine's failure arm to report
// remaining work.
let mut search = match Search::run(resources, start, near, scratch, *budget, quantum)
.map_err(search_error)?
{
// A failed run reports the work it left (perex 0.1.10), so the budget
// records what the failed call spent, as a failed search did.
let run =
Search::run(resources, start, near, scratch, *budget, quantum).map_err(|failed| {
*budget = Budget::new(failed.remaining_work);
search_error(failed.error)
})?;
let mut search = match run {
Run::Finished(mut finished) => {
*budget = Budget::new(finished.remaining_work());
let position = finished.position();
Expand Down Expand Up @@ -554,18 +550,14 @@ pub(crate) fn find_near<'mem, S: ImmutableSubject<Error = OwnerError>>(

poll()?;
let buffers = MatchBuffers::new(memory, size)?;
// On an error that is not a capacity request -- WorkLimit,
// InvalidProgram, ChangedResources, Cancelled -- `run` returns Err and
// drops the scratch and the remaining budget, where `new` + `advance`
// left a Search to read `remaining_work()` from. So `*budget` keeps its
// entry value and under-counts what the failed call spent. WORK is
// usize::MAX on every path here, so nothing observes it today; if a
// finite execution budget is ever reintroduced (see #10164/#10165),
// this stops being free and wants the engine's failure arm to report
// remaining work.
let mut search = match Search::run(&resources, start, near, buffers, *budget, quantum)
.map_err(search_error)?
{
// A failed run reports the work it left (perex 0.1.10), so the budget
// records what the failed call spent, as a failed search did.
let run =
Search::run(&resources, start, near, buffers, *budget, quantum).map_err(|failed| {
*budget = Budget::new(failed.remaining_work);
search_error(failed.error)
})?;
let mut search = match run {
Run::Finished(mut finished) => {
*budget = Budget::new(finished.remaining_work());
let position = finished.position();
Expand Down
9 changes: 7 additions & 2 deletions tests/release/packages/next-app-route/provider/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading