First tagged release since v0.5.178 — 115 commits of accumulated work. Headline changes: generational mark-sweep GC and SSO are now default ON, JSON parsing went tape-based + lazy by default, Windows toolchain dropped its Visual Studio dependency, and Native UI grew end-to-end notification support on iOS + Android.
Highlights
- Generational mark-sweep GC default ON — Phases A-D land the shadow stack, write barriers, nursery/old-gen split, non-moving tenuring, copying evacuation pass, and per-cycle idle-block return-to-OS.
PERRY_GEN_GC=0reverts (bisection only). (v0.5.217 → v0.5.239) - SSO (Small String Optimization) default ON — runtime infrastructure + codegen three-way PropertyGet branch + consumer arms behind
PERRY_SSO_FORCEwhile baking, then default-flipped at v0.5.216. (v0.5.213 → v0.5.216) - JSON parsing rebuilt — schema-directed
JSON.parse<T>(blob), tape-based parse foundation, lazy parse + lazy stringify (default ON), per-element sparse materialization, walk-cursor + adaptive materialize threshold. (v0.5.200 → v0.5.210) - Windows lightweight toolchain — winget LLVM + xwin, no Visual Studio needed (#176, v0.5.199); plus actionable clang-missing / link.exe error messages and
perry doctorLLVM checks. - visionOS simulator support —
--target visionos-simulator(v0.5.185).
Performance
- JSON: lazy parse default ON (v0.5.210), per-element sparse materialization (v0.5.208), NEON/SSE2 string scanner (v0.5.197).
- GC: arena block size 8 MB → 1 MB (v0.5.196), trigger threshold 128 MB → 64 MB (v0.5.198), idle nursery blocks returned to OS (v0.5.235).
- Buffer.alloc fast-path via per-thread bump slab (#92, v0.5.190); BigInt arena alloc +
BigInt(str) ===fix (#92, v0.5.187);parseFloatzero-alloc +Infinityfix (#92).
Runtime / Codegen Fixes
- JSON:
JSON.stringifyof plain f64 segfaulted (v0.5.286); restore#[no_mangle]onjs_json_stringify(v0.5.211). - NaN:
NaN==NaN+ ECMAScript number formatting (v0.5.281);NaN/InfinityToInt32 in(x) | 0(v0.5.280); SSO + property-read NaN bug (v0.5.279). - Promises: microtask FIFO + thrown-handler propagation (v0.5.284);
Promise.all/race/anynon-promise discrimination (v0.5.263);Promise.allSettlednon-Promise values;queueMicrotasknever running +performance.now()always 0 (#156, v0.5.180). - Codegen: cross-module class getters/setters returned undefined (twice — c473934, 2a08855); inline pass remaps closure captures (v0.5.273); don't inline functions with rest params (v0.5.278); i32 loop counter for number-typed bounds (#168, v0.5.188);
js_try_endonreturninside try body; FFI manifest consumption for native-library ABI; for-loopcontinueskipping update on--target web(#137). fs.readFileSync(path)returns Buffer when no encoding (v0.5.277); BigIntfromTwos/toTwostwo's complement (v0.5.255);console.timeresolution (#155, v0.5.181);Int32Arraylength=0 +Uint8ClampedArrayno-clamp + negative NaN (#157, v0.5.184);isWellFormed/toWellFormedlone-surrogate detection (#29).- WASM: drop excess args at WASM call sites (#183, v0.5.205).
- Type predicates + lazy audit (v0.5.212); HIR silent fall-throughs in lowerer + monomorph (v0.5.249).
Stdlib & Node Compat (#187 follow-ups)
- Redis (ioredis) end-to-end + dispatch-table-symbol-mismatch fix (v0.5.270); pg + mongo async-factory pattern (v0.5.275); AsyncLocalStorage end-to-end (v0.5.261); decimal.js (v0.5.259); commander runtime + codegen
.action()invocation (v0.5.250);new T()bug on EE/LRU/WSS (v0.5.252); Buffer numeric reads intrinsified (#92, v0.5.183). - Fastify end-to-end integration test + two dispatch fixes (#174, v0.5.189); mysql2 + pg
connection.execute()param binding (#143, v0.5.182).
Native UI
- Apple (iOS / macOS):
notificationSend(#94, ui-ios v0.5.193), client-side remote-push token + receive (#95, v0.5.243), scheduled + cancellable local notifications (#96, v0.5.244), notification tap callback (#97, v0.5.254). - Android:
notificationSend(#94, v0.5.256), schedule + cancel notifications (#96, v0.5.260), notification tap callback (#97, v0.5.258), FCM register + receive (#95, v0.5.262).
Platform / Toolchain
- Windows: lightweight toolchain (#176, v0.5.199);
find_lld_link/find_perry_windows_sdkcfg gate hotfix (v0.5.201);/SUBSYSTEM:CONSOLEfor non-UI PE builds (#120, v0.5.179); actionable clang/link.exe error messages (#176 follow-ups, v0.5.191/.192). - npm:
libc:glibcfield onlinux-x64andlinux-arm64packages (#116/#161).
Documentation & Benchmarks
- Polyglot benchmark suite expansions: Kotlin + JSON polyglot (v0.5.241/.242), simdjson + AssemblyScript+json-as peers (v0.5.274),
loop_data_dependent+bench_field_accesslanded (v0.5.272). - Methodology hardening: RUNS=11 median + p95 + σ + macOS pinning (v0.5.248); 04_array_read 211 MB peak RSS explained (v0.5.276); FP-contract caveat (FMA-contract vs no-contract clustering) on
bench_loop_data_dependent(v0.5.293). - Node TS-strip leveling:
json_polyglot/run.shprecompiles Node TS to .mjs as untimed setup so Node isn't charged for--experimental-strip-typesruntime parse (v0.5.293). - GC academic + industry lineage appendix; Phase D roadmap closeout (v0.5.239/.240).
- CLAUDE.md condense — 124 verbose Recent Changes entries (~242 KB) migrated to CHANGELOG.md, file went 254 KB → 12 KB (v0.5.292).
Repo & CI Hygiene
chore(repo)v0.5.293: untrack 465 Android Gradle cache files, gitignoreandroid-build/.gradle//build//app/build/,docs/examples/_reports/, external demoassets/, and stray repro binaries.- CI macos-14 jobs no longer OOM on disk space (v0.5.289-.291).
- Memory stability suite for RSS-leak + GC-aggression regressions (v0.5.233).
- Stub-audit cleanups:
test_json,test_gap_console_methods,test_gap_class_advancedremoved fromknown_failures.json.
Escape Hatches
PERRY_GEN_GC=0— revert generational GC to full mark-sweep.PERRY_SHADOW_STACK=0— disable shadow-stack precise roots.PERRY_GEN_GC_EVACUATE=1— opt into copying evacuation (default OFF, work-saving on workloads where nothing tenures).PERRY_WRITE_BARRIERS=1— opt into codegen-emitted write barriers (runtime barrier always exists).PERRY_GC_DIAG=1— per-cycle GC diagnostics.