Repository navigation
Conversation
Bumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@9c091bb...3d3c42e) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
…ision, double-array reduce, float loop, byte-array from seq)
…O-065) fastBinaryFixnum becomes fastBinaryNumber: a double paired with a double or fixnum computes + - * < <= > >= in f64, exactly what promote.*Promoting and math.pairwise do once either operand is a double. = not= mod rem quot still defer to the builtin (cross-category equality, float sign-of-zero rules). The float arm sits out of line (fastNonFixnum) so the fixnum dispatch keeps its shape; inline, it cost 04_arith_loop +9%. diff_test pins 16 float cases VM == TreeWalk. User instructions, ReleaseSafe -Dwasm, taskset -c 2, min of 2-3, O-064 commit -> this commit: 40 seq_dot_1k 13.25G -> 11.65G -12% 41 seq_dot_100k 13.74G -> 12.21G -11% 44 float_loop_recur 2.52G -> 1.86G -26% 02 fib_loop 67.0M -> 66.8M 0% 04 arith_loop 778.0M -> 810.8M +4.2% (accepted: dispatch shape) 01 fib_recursive 355.8M -> 362.4M +1.8% Card: CLJW-NUMERIC-SEQ-PERF (20261021235636-3459e0ce).
agent, locking, concurrency_stress, the java.io family, reducers, repl, json_fs, tokenizer_long_input, extend_via_metadata and bfs_queue_gc now run in the shared suite image. shutdown-agents cases stay in a child cljw since the call is process-global. Divergence pins repointed to the suites; e2e ceiling 322 -> 305. Smell-audited: 0: no smells; scripts deleted with their run_all rows and fixtures
# Conflicts: # .scratch/RESUME.md
… a suite gc_torture, http_client, http_server, load_file_source, repl_classpath, stdin_read_line, vm_error_loc_sidecar, wasm_polyglot and eval_budget each assert something only a fresh cljw process shows (startup env, a bound port, stdin, rendered stderr, exit codes, external toolchains), so they carry the e2e-process-boundary marker with the reason. eval_budget's in-process cljw.eval/with-budget cases move to suites/eval_budget_test. Counted scripts 305 -> 296. Smell-audited: 0: no smells; each marker reason checked against the script body
phase16_wasm_component, _component_multiexport and _component_budget and the catchability half of phase16_wasm_ffi become deftests: wasm_component_test, wasm_component_multiexport_test (the ADR-0135 echo table, one assertion per row), wasm_component_budget_test and wasm_ffi_catch_test. wasm_ffi keeps only the exit-time leak report and is marked a process boundary. Probe fixtures deleted, debt refs repointed. Counted scripts 296 -> 292. Smell-audited: 0: no smells; every probe marker kept as an assertion message
The linear-memory probe and the engine-selection probe become wasm_memory_test and wasm_engine_select_test, one assertion per probe label. scripts/run_wasm_gate.sh now also runs every wasm_*_test suite so the wasm-only quick path keeps its coverage. Counted scripts 292 -> 290. Smell-audited: 0: no smells; run_wasm_gate exercised against the suites
test/run_all.sh: both sides deleted rows for migrated scripts (phase15 set_bang/stm_dosync by #89, phase16 locking/agent/concurrency_stress here); none of the five scripts exists after the merge, so neither side's rows stay. check_e2e_count.sh baseline is the combined count: 231 (18 exempt by marker). check_e2e_reach and check_e2e_dup pass. Smell-audited: 0: merge of two deletions plus the recomputed ceiling
Each node of a one-coll map/filter/take/iterate chain allocated an interpreted arity-0 closure and re-entered eval to run its body. Over an unchunked source such as (range) = (iterate inc 0) that was one closure and one eval re-entry per element per layer. A LazySeq can now hold a builtin step plus two operands (lazy_seq.allocNative). The steps in lang/primitive/lazy_step.zig build the same nodes as the clj bodies: chunk-cons over a chunked source via the O-032 drains, cons plus the next node otherwise. filter skips rejected elements and empty chunks within one realization. iterate does not call f for its head, as clj's Iterate. take keeps the interpreted body for a non-integer n. lazy_chain (3 reps): 1208 ms -> ~270 ms, bb 141 ms. Realization counts are pinned against bb in lazy_step_test.clj. VM and tree_walk give the same results under --compare. Smell-audited: 1: one native-step slot on LazySeq instead of a node type per producer
lazy_chain 13.75x -> 2.28x bb on the cherry-pick of #91 onto v1.15.4 staging (bench/vs_bb -n 3, load 12.6). Smell-audited: 1: changelog and bench row only, no code
# Conflicts: # .dev/optimizations.md
Smell-audited: 1: changelog only, no code
zwasm d77568a0 (BuddhiLW/zwasm fix/wasi-p2-adapter-imports, upstream zwasm/zwasm#634): a component built with the wasi_snapshot_preview1 adapter no longer fails wasm/load-component with UnknownImport. The adapter's env::memory re-export resolves, and filesystem-error-code plus the 0.2 clock resolution rows are served. This pins a fix branch only until fork #7 merges (fork Actions are disabled); the merge has the same tree, so the .hash carries over.
perf(lazy): native lazy nodes for map/filter/take/iterate (lazy_chain 13.75x -> 2.28x bb)
# Conflicts: # CHANGELOG.md
A vector's TailNode carried an inline [32]Value (a 272-byte cell for a
2-vector) and an ArrayMap an inline [16]Value (152 bytes for a 2-key map).
Both now keep their slots as trailing storage in the same GC cell
(allocWithTail, the ADR-0184 shape), sized to len / 2*count and read
through items() / entries(). Every persistent change copies the cell
anyway, so the reserve bought nothing.
200k retained {:id i :v [i (inc i)]}: last_live 97.2 -> 29.6 MB
(486 -> 148 B per entry). gc_churn: bytes_alloc 497 -> 175 MB, peak RSS
353 -> 160 MB. Instructions per literal are unchanged (perf stat,
pinned): the remaining time gap to bb is VM dispatch, recorded in O-091.
Smell-audited: 1: removes a fixed-capacity reserve that no persistent op used; one cell per node kept, no new seam
A String paid two allocations: the GC cell and a separate gpa.dupe of its bytes, freed again by the per-tag finaliser at sweep. perf of (count (str i)) in a loop showed libc malloc/free at about 12% of samples. Payloads up to page_heap.max_small_bytes - @sizeof(String) now live in the tail of the String's own cell (allocWithTail). A storage enum in a former padding byte tells the finaliser and ownedBytes which arm applies; larger payloads keep the owned infra block. The inline alloc runs inside a fabrication region, since byte_view may be the tail of an unrooted String. Pinned user instructions: str loop 2790 -> 2300 per iteration over the empty loop; vs_bb string_ops 5959M -> 5219M, gc_churn 8369M -> 8011M. Smell-audited: 1: stale module doc that argued against inline storage rewritten; no address-adjacency test, explicit storage tag instead
perf(eval): inline f64 arith/compare in the VM intrinsics (O-065) + numeric seq bench cells
# Conflicts: # CHANGELOG.md
Splits gc_churn into the retained build, the full churn loop, the small map+vector literal, (str i) and the empty recur loop, timed per piece. Runs on cljw and bb alike. The measurements behind CLJW-PERF-SMALL-LITERAL, CLJW-PERF-STR-1ARG and CLJW-PERF-RECUR-LOOP came from it. Smell-audited: 1: bench probe only, no runtime code
# Conflicts: # CHANGELOG.md
perf(collection): size vector tails and array maps to their contents
# Conflicts: # CHANGELOG.md
perf(string): store short string payloads inline in the GC cell
threshold = max(floor, last_live) instead of max(floor, 2 * last_live). Peak committed heap is about live + threshold, so the 2x growth factor held a large live set near 3x itself in RSS. Shrinking the retained empty pages instead does not lower the peak (the next cycle maps them again, pages_released 89 -> 11117), so the growth factor is the lever. Adds an adaptiveThreshold unit test and a heap-return suite case (peak committed under 2.5x live; base measures 3.0x, new 2.0x). Smell-audited: 1: one-line policy change in gc_trigger, no new knob, retention budget untouched, three doc comments updated
The bench-vs-bb job restores the gate's x86_64-linux .zig-cache read-only. That cache can hold a WriteFiles manifest (stub_wf, which writes bootstrap_sources_stub.zig for cache_gen) whose o/<digest> output dir is gone. Zig then fails with "failed to check cache ... file_hash FileNotFound" instead of rebuilding. It hit #99 twice on 2026-10-24, from a cache saved by a green gate run, so the save-side guard in ci.yml (never save a cancelled job) does not cover this case. The job never saves the cache, so the fix is local: on a failed build, drop .zig-cache and build cold once. Smell-audited: 1: read-only consumer recovers locally; no save-side change without a reproducer
…line fastBinaryNumber Recovered work-in-progress from the previous session (CLJW-PERF-RECUR-LOOP). Smell-audited: 1: WIP recovery, no new smells; cold ops dispatched via toCold prong
feat(examples): fractal-zoom demo on cljw zwasm and in the browser
…by the trifecta jvm/ is CPPB-stratified around fractal.renderer/IRenderer: - domain: fractal.tile (Tile, EscapeField), fractal.palette (the one colouring rule, as data), fractal.golden (golden.edn, pure verdicts). - adapters: raster deftm escape loop (all cores, 1 thread), raster SIMD lanes (par/map + blend), CUDA fp64 (--fmad=false, golden-exact) and fp32 via NVRTC to CUBIN on a dedicated GPU thread, plain-Clojure oracle. - collect: fractal.engines discovers renderers; an unavailable one (no GPU) is data, not a start-up failure. - boundary: fractal.http (tile protocol + CORS), fractal.main, fractal.bench. Renderers compute only the escape field; the palette runs once above the port, so every exact renderer paints identical bytes. Tests: golden (every exact renderer vs golden.edn), test.check properties (renderers vs the oracle bit for bit, palette and tile laws, HTTP frame), mutation (6 escape and 4 palette mutants must be killed). The mutation suite exposed that no golden pixel sat on |z|^2 = 4, so `<` vs `<=` passed; the new "tip" view puts a pixel on c = -2 and kills it. "deep" (1024x768, 4096 iter, 2.39e9 iterations) is the heavy view.
Merges origin/main first so the v1.15.5 stamp is on staging and these entries sit under [Unreleased].
…ated e2e
cljw: cljw/{tile,renderer,engines}.clj put every wasm kernel (Zig, Zig
simd128, C, Rust on zwasm jit and interp) and plain Clojure behind one
IRenderer, discovered into a registry. server.clj and bench.clj are thin
boundaries over it; bench.clj now judges every frame against golden.edn.
Page: engines.cljs is a protocol with WasmKernel, JsRaster and RemoteTiles
adapters; discovery fills a registry, so nothing parses an engine name.
Servers advertise inexact engines (cuda-f32), which bench parity skips.
Found by the hive-cljs suite and fixed: the root rendered nothing (hiccup
handed to React instead of reagent.dom.client/render), window.fractal
clobbered the fractal.* namespace root (now window.fractalApi), an
id/class tag order reagent rejects, and setPointerCapture throwing on an
untracked pointer.
Gate: phase16_fractal_kernel.sh runs the :ci golden views on 8 engines
(16 frames) and rebuilds the Zig, C and Rust kernels byte for byte.
kernel.c's recipe is now zig cc (no system wasm-ld); kernel_rust.wasm is
rebuilt by its header recipe.
Tests: hive-cljs 10/10 scenarios against the live servers, cljs view laws
(test.check), JVM golden + property + mutation (11 tests, 58 assertions).
…op 20 lines check_surface_marker reads only the first 20 lines; the byte-array docstring pushed `Impl deps:` and `Clojure peer:` to lines 21 and 22. The docstring is rewrapped to the same content in two fewer lines. On macOS `wc -c` pads its count, so the /bytes length check strips spaces, and phase16_fractal_kernel runs unbounded without timeout or gtimeout like its sibling gates instead of failing. Smell-audited: 1: comment rewrap and two portability fixes, no behaviour change
release: v1.15.6, byte-array HTTP bodies and the fractal example
A formula is one orbit step in a small expression language (fractal.formula): Mandelbrot, Burning Ship, Tricorn and Multibrot z^3, each on the c-plane or as a Julia set (the seed is a separate axis). Every backend compiles the same expression: the oracle to a Clojure fn, raster to a generated deftm per formula and seed, CUDA to generated C (escape.cu is gone). They agree bit for bit. Renderers state what they render in describe (:formulas, :julia?); one that states nothing stays Mandelbrot only, so the wasm kernels, the browser engines and cljw need no change. /tile refuses the rest with a 400, and the page offers only engines whose caps cover the fractal. Tests: golden views for every formula on both seeds; 149 step mutants generated from the formula data, all killed; the compiled step equals an independent interpreter; exact symmetry laws; the unit-disk Julia set; page scenarios for formula golden, switch, Julia at the cursor, refusal.
README, server.clj and index.html keep the branch side: the page moved to web/ (re-frame) and server.clj already requires clojure.string. The new phase16_fractal_server gate now checks the registry server: eight engines and four kernels on /engines, the page on /, every kernel's bytes, identical tiles on all eight engines, and the 400 refusals of an unknown engine and of a formula cljw does not render.
…e's server The bare canvas rule made the rolling ms/frame chart absolutely positioned over the page, hiding the header controls (seen live on cljw.buddhilw.com/fractal/). Scope it to the fractal view, show '-' for a frame under the timer resolution, and let the bench table scroll. phase16_fractal_server backgrounded a shell function, so $! named the subshell and the EXIT trap left timeout and cljw holding port 8159. Exec the bounding process in the subshell instead.
Fractal demo: Zig, C, Rust, Clojure, raster and CUDA engines behind one renderer port
…actions/actions/checkout-7.0.1 # Conflicts: # .github/workflows/release.yml
The dependabot bump predates bench-vs-bb.yml, mutation.yml and two of the release.yml jobs, which still pinned 7.0.0. Every workflow now uses the same checkout pin.
#111 replaced docs/examples/fractal/index.html with the ClojureScript app under web/, so the page fixes move there: the canvas rule was already scoped to #view, #chart becomes a block of the stats panel, and the Miter/s rate goes through view/mits, which is nil for a frame under the timer resolution so the HUD, live table and bench show '-' instead of Infinity. The gate server leak fix applies unchanged to the rewritten phase16_fractal_server.sh.
…ns/checkout-7.0.1 ci: bump actions/checkout from 7.0.0 to 7.0.1
test: migrate phase16 e2e scripts to cljw clojure.test suites
fix(examples): fractal chart covered the header; gate server leak
CHANGELOG [Unreleased] keeps both sections: this branch's Changed entry for reduce-kv and staging's Fixed entry for the fractal page and gate.
fix(hierarchy): derive raises clj's AssertionError, class ancestors reach Object; retire AD-068
The glibc mmap-threshold entry and staging's derive and ancestors entries had both landed under the released [1.15.5] section; both move to [Unreleased] Fixed, where unreleased changes belong.
perf(reduce): index vector reduce-kv in Zig
fix(gc): pin glibc M_MMAP_THRESHOLD at process start
…ased PR #111 merged without a CHANGELOG entry; the release stamps only what [Unreleased] holds.
release: v1.15.7, reduce-kv in Zig, clj's derive errors, glibc mmap pin, fractal formulas
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.
Brings clojurewasm/ClojureWasm main up to v1.15.7 (fork tag 706d327), covering v1.15.5, v1.15.6 and v1.15.7.
into; cheaper small GC cells;inc/deccompile to direct ops.cljw.http.serveraccepts a byte-array:bodyverbatim; thedocs/examples/fractal/Mandelbrot example with its two e2e gates.reduce-kvon vectors indexes in Zig (-71.7% instructions);deriveraises clj's own errors and class ancestors reachObject; glibc mmap threshold pinned at startup; the fractal example grows to nineteen engines and four formulas with Julia sets.See CHANGELOG.md [1.15.5], [1.15.6] and [1.15.7].