Skip to content

Add zlib-rs as an autogated backend for node:zlib - #7109

Open
guybedford wants to merge 1 commit into
mainfrom
gbedford/zlib-rs
Open

Add zlib-rs as an autogated backend for node:zlib#7109
guybedford wants to merge 1 commit into
mainfrom
gbedford/zlib-rs

Conversation

@guybedford

Copy link
Copy Markdown
Contributor

This adds zlib-rs (libz-rs-sys), the memory-safe Rust implementation of the zlib C API, as an alternative backend for node:zlib's zlib streams, selected per context by the new compression-rs autogate. The native chromium zlib remains the default.

The z_stream ABI is identical between the two implementations, so the integration is a function dispatch table (ZlibDispatch) consulted at context construction:

  • zlib-rs symbols are bridged from a translation unit that does not include the chromium zlib headers, since chromeconf.h renames all standard zlib identifiers (Cr_z_ mangling) — which also makes the unprefixed zlib-rs symbol names collision-free in the binary
  • dictionaries, gzip header handling, and custom zalloc/zfree allocators (memory accounting) flow through unchanged
  • bench-zlib measures both backends on the node:zlib streaming workload (1MB in 16KB chunks, level 6): zlib-rs is 34% faster on deflate and 17% faster on inflate than the SIMD-enabled chromium zlib

The full node:zlib test matrix passes with the gate both off and on (the @all-autogates variants exercise the zlib-rs path, including the dictionary and resizable-buffer tests).

@guybedford
guybedford requested review from a team as code owners August 24, 2026 23:02
Backs the shared ZlibStream core with zlib-rs (libz-rs-sys), the
memory-safe Rust implementation of the zlib C API, selected per stream by
the new compression-rs autogate. This covers both node:zlib and the web
CompressionStream/DecompressionStream API. The native chromium zlib
remains the default.

The z_stream ABI is identical between the two implementations, so the
integration is a function dispatch table (ZlibDispatch) consulted at
stream construction; node's dictionary/params escape hatches route
through the same table via ZlibStream::dispatch(). The zlib-rs symbols
are bridged from a translation unit that does not include the chromium
zlib headers, since chromeconf.h renames all standard zlib identifiers
(Cr_z_ mangling) - which is also why the unprefixed zlib-rs symbol names
are collision-free in the binary.

bench-zlib measures both backends on the streaming workload (1MB in 16KB
chunks, level 6): zlib-rs measures ~34% faster deflate and ~17% faster
inflate than the SIMD-enabled chromium zlib.

@jasnell jasnell left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This would have been more difficult before the api/compression.{h/c++} change I just landed ;-)

"build_file_content": "exports_files([\"bin/wasm-opt\"])"
},
{
"name": "binaryen_linux_arm64",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Aside: I should make our script handle multi-arch packages like this more nicely.

};

// Selects the backing zlib implementation via the compression-rs autogate.
const ZlibDispatch& getZlibDispatch();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: getZlibDispatch() to set up vs dispatch() to access isn't the clearest to me.

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.

3 participants