FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[pull] main from cloudflare:main by pull[bot] · Pull Request #281 · Reality2byte/workerd · GitHub

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

Filter by extension

Filter by extension .bazel  (6) .c++  (7) .h  (6) .js  (1) .lock  (1) .rs  (1) .toml  (1) .zlib  (1) All 8 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
39 changes: 5 additions & 34 deletions build/BUILD.zlib
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
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ cc_library(
# For zlib to be found using <zlib.h> before system zlib, use this flag for the include to also be added using isystem.
includes = ["."],
local_defines = ["ZLIB_IMPLEMENTATION"],
visibility = ["//visibility:public"],
)

cc_library(
Expand Down Expand Up @@ -226,42 +227,12 @@ filegroup(

cc_library(
name = "zlib",
srcs = [":zlib_files"],
copts = zlib_warnings,
features = ["-parse_headers"],
# Duplicate definitions here since we want to avoid non-local defines, some of them are needed
# here. This excludes INFLATE_CHUNK_* which is only needed in zlib_inflate_chunk_simd.
local_defines = ["ZLIB_IMPLEMENTATION"] + select({
"@platforms//cpu:x86_64": [
"ADLER32_SIMD_SSSE3",
"CRC32_SIMD_SSE42_PCLMUL",
"DEFLATE_SLIDE_HASH_SSE2",
"DEFLATE_CHUNK_WRITE_64LE",
],
"@platforms//cpu:aarch64": [
"ADLER32_SIMD_NEON",
"CRC32_ARMV8_CRC32",
"DEFLATE_SLIDE_HASH_NEON",
"DEFLATE_CHUNK_WRITE_64LE",
],
}) + select({
":x86_linux": ["X86_NOT_WINDOWS"],
":x86_macos": ["X86_NOT_WINDOWS"],
":x86_windows": ["X86_WINDOWS"],
":arm64_linux": ["ARMV8_OS_LINUX"],
"arm64_macos": ["ARMV8_OS_MACOS"],
"arm64_windows": ["ARMV8_OS_WINDOWS"],
"//conditions:default": [],
}),
defines = ["CHROMIUM_ZLIB_NO_CHROMECONF"],
visibility = ["//visibility:public"],
deps = [
":zlib_adler32_simd",
":zlib_inflate_chunk_simd",
":zlib_slide_hash_simd",
] + select({
"@platforms//cpu:x86_64": [":zlib_crc32_simd"],
"@platforms//cpu:aarch64": [":zlib_arm_crc32"],
}),
":zlib_common_headers",
"@@//src/rust/zlib-rs",
],
)

# Chromium zlib includes some custom compression utils that are not present in mainline zlib but
Expand Down
9 changes: 4 additions & 5 deletions build/deps/rust.MODULE.bazel
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ rust.toolchain(
allocator_library = "@rules_rust//ffi/rs:empty",
edition = "2024",
extra_rustc_flags_triples = {
# Enable ISA extensions matching the ones used for C++. The clmul feature is not included as
# it is still "unstable" as of 1.86.0.
"x86_64-unknown-linux-gnu": ["-Ctarget-feature=+sse4.2"],
"x86_64-apple-darwin": ["-Ctarget-feature=+sse4.2"],
"x86_64-pc-windows-msvc": ["-Ctarget-feature=+sse4.2"],
# Enable ISA extensions matching the ones used for C++.
"x86_64-unknown-linux-gnu": ["-Ctarget-feature=+sse4.2,+pclmulqdq"],
"x86_64-apple-darwin": ["-Ctarget-feature=+sse4.2,+pclmulqdq"],
"x86_64-pc-windows-msvc": ["-Ctarget-feature=+sse4.2,+pclmulqdq"],
"aarch64-unknown-linux-gnu": ["-Ctarget-feature=+crc"],
# No options needed for aarch64-apple-darwin: CRC feature is enabled by default.
},
Expand Down
16 changes: 16 additions & 0 deletions deps/rust/Cargo.lock

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

4 changes: 4 additions & 0 deletions deps/rust/Cargo.toml
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
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ capnp-rpc = "0"
clang-ast = "0"
encoding_rs = "0"
flate2 = "1"
# Memory-safe Rust implementation of the zlib C API, evaluated as a
# replacement backend for compression streams. rust-allocator only:
# zalloc/zfree left NULL use Rust's global allocator.
libz-rs-sys = { version = "0.6", default-features = false, features = ["std", "rust-allocator", "export-symbols"] }
futures = "0"
libc = "0"
lol_html_c_api = { git = "https://github.com/cloudflare/lol-html" }
Expand Down
7 changes: 7 additions & 0 deletions src/rust/zlib-rs/BUILD.bazel
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
load("//:build/wd_rust_crate.bzl", "wd_rust_crate")

wd_rust_crate(
name = "zlib-rs",
visibility = ["//visibility:public"],
deps = ["@crates_vendor//:libz-rs-sys"],
)
5 changes: 5 additions & 0 deletions src/rust/zlib-rs/lib.rs
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Links libz-rs-sys (the memory-safe Rust implementation of the zlib C API)
// into the binary. The #[no_mangle] C symbols (deflate, inflate, ...) are
// pulled in by C++ callers referencing them; the re-export below makes the
// crate a required part of the link.
pub use libz_rs_sys::*;
13 changes: 11 additions & 2 deletions src/workerd/api/BUILD.bazel
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
Original file line number Diff line number Diff line change
Expand Up @@ -279,15 +279,24 @@ wd_cc_library(
# the TypeScript streams implementation's codec handle.
wd_cc_library(
name = "compression",
srcs = ["compression.c++"],
hdrs = ["compression.h"],
srcs = [
"compression.c++",
"zlib-rs-bridge.c++",
],
hdrs = [
"compression.h",
"zlib-rs-bridge.h",
],
visibility = ["//visibility:public"],
deps = [
"//src/rust/zlib-rs",
"//src/workerd/io:features",
"//src/workerd/jsg",
"//src/workerd/util:autogate",
"@capnp-cpp//src/kj/compat:kj-brotli",
"@capnp-cpp//src/kj/compat:kj-gzip",
"@nbytes",
"@zlib",
"@zstd",
],
)
Expand Down
108 changes: 99 additions & 9 deletions src/workerd/api/compression.c++
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

#include "compression.h"

#include "zlib-rs-bridge.h"

#include <workerd/io/features.h>
#include <workerd/jsg/util.h>
#include <workerd/util/autogate.h>

#include <nbytes.h>

Expand Down Expand Up @@ -41,6 +44,93 @@ void CompressionAllocator::FreeForZlib(void* opaque, void* pointer) {
JSG_REQUIRE(allocator->allocations.erase(pointer), Error, "Zlib allocation should exist"_kj);
}

// =======================================================================================
// ZlibBackend

namespace {

// Wrappers over the native (chromium) zlib. deflateInit2/inflateInit2 are
// macros injecting ZLIB_VERSION and sizeof(z_stream), hence the indirection.
int nativeDeflateInit2(z_stream* strm, int level, int windowBits, int memLevel, int strategy) {
return deflateInit2(strm, level, Z_DEFLATED, windowBits, memLevel, strategy);
}
int nativeInflateInit2(z_stream* strm, int windowBits) {
return inflateInit2(strm, windowBits);
}

constexpr ZlibBackend NATIVE_ZLIB = {
.initDeflate = &nativeDeflateInit2,
.initInflate = &nativeInflateInit2,
.runDeflate = &deflate,
.runInflate = &inflate,
.endDeflate = &deflateEnd,
.endInflate = &inflateEnd,
.resetDeflate = &deflateReset,
.resetInflate = &inflateReset,
.setDeflateParams = &deflateParams,
.setDeflateDictionary = &deflateSetDictionary,
.setInflateDictionary = &inflateSetDictionary,
};

// Wrappers over zlib-rs; the bridge takes void* because its translation unit
// cannot see the chromium zlib types (see zlib-rs-bridge.h).
int rsDeflateInit2(z_stream* strm, int level, int windowBits, int memLevel, int strategy) {
return zlibrs::initDeflate(strm, level, windowBits, memLevel, strategy);
}
int rsInflateInit2(z_stream* strm, int windowBits) {
return zlibrs::initInflate(strm, windowBits);
}
int rsDeflate(z_stream* strm, int flush) {
return zlibrs::runDeflate(strm, flush);
}
int rsInflate(z_stream* strm, int flush) {
return zlibrs::runInflate(strm, flush);
}
int rsDeflateEnd(z_stream* strm) {
return zlibrs::endDeflate(strm);
}
int rsInflateEnd(z_stream* strm) {
return zlibrs::endInflate(strm);
}
int rsDeflateReset(z_stream* strm) {
return zlibrs::resetDeflate(strm);
}
int rsInflateReset(z_stream* strm) {
return zlibrs::resetInflate(strm);
}
int rsDeflateParams(z_stream* strm, int level, int strategy) {
return zlibrs::setDeflateParams(strm, level, strategy);
}
int rsDeflateSetDictionary(z_stream* strm, const kj::byte* dictionary, uint32_t dictLength) {
return zlibrs::setDeflateDictionary(strm, dictionary, dictLength);
}
int rsInflateSetDictionary(z_stream* strm, const kj::byte* dictionary, uint32_t dictLength) {
return zlibrs::setInflateDictionary(strm, dictionary, dictLength);
}

constexpr ZlibBackend ZLIB_RS = {
.initDeflate = &rsDeflateInit2,
.initInflate = &rsInflateInit2,
.runDeflate = &rsDeflate,
.runInflate = &rsInflate,
.endDeflate = &rsDeflateEnd,
.endInflate = &rsInflateEnd,
.resetDeflate = &rsDeflateReset,
.resetInflate = &rsInflateReset,
.setDeflateParams = &rsDeflateParams,
.setDeflateDictionary = &rsDeflateSetDictionary,
.setInflateDictionary = &rsInflateSetDictionary,
};

} // namespace

const ZlibBackend& selectZlibBackend() {
if (util::Autogate::isEnabled(util::AutogateKey::COMPRESSION_RS)) {
return ZLIB_RS;
}
return NATIVE_ZLIB;
}

// =======================================================================================
// ZlibStream

Expand All @@ -60,10 +150,10 @@ kj::Maybe<int> ZlibStream::init(Mode mode, Options options) {
int result = [&]() {
switch (mode) {
case Mode::COMPRESS:
return deflateInit2(&stream, options.level, Z_DEFLATED, options.windowBits,
options.memLevel, options.strategy);
return backend.initDeflate(
&stream, options.level, options.windowBits, options.memLevel, options.strategy);
case Mode::DECOMPRESS:
return inflateInit2(&stream, options.windowBits);
return backend.initInflate(&stream, options.windowBits);
}
KJ_UNREACHABLE;
}();
Expand All @@ -79,9 +169,9 @@ kj::Maybe<int> ZlibStream::reset() {
int result = [&]() {
switch (mode) {
case Mode::COMPRESS:
return deflateReset(&stream);
return backend.resetDeflate(&stream);
case Mode::DECOMPRESS:
return inflateReset(&stream);
return backend.resetInflate(&stream);
}
KJ_UNREACHABLE;
}();
Expand All @@ -98,9 +188,9 @@ int ZlibStream::end() {
ended = true;
switch (mode) {
case Mode::COMPRESS:
return deflateEnd(&stream);
return backend.endDeflate(&stream);
case Mode::DECOMPRESS:
return inflateEnd(&stream);
return backend.endInflate(&stream);
}
KJ_UNREACHABLE;
}
Expand All @@ -109,9 +199,9 @@ int ZlibStream::run(int flush) {
KJ_ASSERT(initialized && !ended, "ZlibStream::run() requires a live stream");
switch (mode) {
case Mode::COMPRESS:
return deflate(&stream, flush);
return backend.runDeflate(&stream, flush);
case Mode::DECOMPRESS:
return inflate(&stream, flush);
return backend.runInflate(&stream, flush);
}
KJ_UNREACHABLE;
}
Expand Down
28 changes: 28 additions & 0 deletions src/workerd/api/compression.h
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
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ class CompressionAllocator final {
// translates to its spec-pinned TypeErrors; node:zlib to Node-fidelity CompressionError
// codes), and node-specific zlib features (dictionaries, deflateParams) reach the structure
// through raw() until they grow shared consumers.
// Backend table over the zlib C API. Two implementations back it: native
// (chromium) zlib and zlib-rs (memory-safe Rust, see zlib-rs-bridge.h). The
// backend is chosen per stream by the compression-rs autogate at construction.
// The z_stream ABI is identical between the two.
struct ZlibBackend {
int (*initDeflate)(z_stream* strm, int level, int windowBits, int memLevel, int strategy);
int (*initInflate)(z_stream* strm, int windowBits);
int (*runDeflate)(z_stream* strm, int flush);
int (*runInflate)(z_stream* strm, int flush);
int (*endDeflate)(z_stream* strm);
int (*endInflate)(z_stream* strm);
int (*resetDeflate)(z_stream* strm);
int (*resetInflate)(z_stream* strm);
int (*setDeflateParams)(z_stream* strm, int level, int strategy);
int (*setDeflateDictionary)(z_stream* strm, const kj::byte* dictionary, uint32_t dictLength);
int (*setInflateDictionary)(z_stream* strm, const kj::byte* dictionary, uint32_t dictLength);
};

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

class ZlibStream final {
public:
enum class Mode { COMPRESS, DECOMPRESS };
Expand Down Expand Up @@ -115,6 +136,12 @@ class ZlibStream final {
return stream;
}

// The zlib implementation backing this stream, for consumer-specific calls
// made through raw().
const ZlibBackend& getZlibBackend() const {
return backend;
}

// The canonical name for a zlib return code (e.g. "Z_DATA_ERROR"); "Z_UNKNOWN_ERROR" for
// unrecognized codes.
static kj::StringPtr errorCodeName(int code);
Expand All @@ -124,6 +151,7 @@ class ZlibStream final {
static kj::Maybe<int> windowBitsForWebFormat(kj::StringPtr format);

private:
const ZlibBackend& backend = selectZlibBackend();
z_stream stream = {};
Mode mode = Mode::COMPRESS;
bool initialized = false;
Expand Down
Loading
Loading

Back | FazBrowse Home | New Git URL