From bfe91a4da67db7af9d50033ed817ef718966469d Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Sat, 22 Aug 2026 18:03:31 -0300 Subject: [PATCH] Upgrade `libdeflate` to v1.26 Signed-off-by: Juan Cruz Viotti --- DEPENDENCIES | 2 +- vendor/libdeflate/common_defs.h | 21 +----- vendor/libdeflate/lib/arm/cpu_features.c | 88 ++++++++++++++++++---- vendor/libdeflate/lib/deflate_compress.c | 7 ++ vendor/libdeflate/lib/deflate_decompress.c | 12 +-- vendor/libdeflate/lib/x86/adler32_impl.h | 1 + vendor/libdeflate/lib/x86/crc32_impl.h | 1 + vendor/libdeflate/libdeflate.h | 9 ++- 8 files changed, 100 insertions(+), 41 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index a4d2c127ee..0bf5f1b26c 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -8,7 +8,7 @@ pyca-cryptography https://github.com/pyca/cryptography 9747d06e83764e7f1ea4c04da wycheproof https://github.com/C2SP/wycheproof 6d7cccd0fcb1917368579adeeac10fe802f1b521 pcre2 https://github.com/PCRE2Project/pcre2 pcre2-10.47 googlebenchmark https://github.com/google/benchmark 378fe693a1ef51500db21b11ff05a8018c5f0e55 -libdeflate https://github.com/ebiggers/libdeflate v1.25 +libdeflate https://github.com/ebiggers/libdeflate v1.26 unicodetools https://github.com/unicode-org/unicodetools final-17.0-20250910 jose-cookbook https://github.com/ietf-jose/cookbook 13692b68bfc18b99557a5b1ed311fd5077bfff04 w3c-json-ld https://github.com/w3c/json-ld-api 8654ac22b6cf4f441d2fee915ae634d36b5a8067 diff --git a/vendor/libdeflate/common_defs.h b/vendor/libdeflate/common_defs.h index a0868d44d9..80307b90cb 100644 --- a/vendor/libdeflate/common_defs.h +++ b/vendor/libdeflate/common_defs.h @@ -159,8 +159,8 @@ typedef size_t machine_word_t; #endif #ifdef _MSC_VER # define MSVC_PREREQ(version) (_MSC_VER >= (version)) -# if !MSVC_PREREQ(1900) -# error "MSVC versions older than Visual Studio 2015 are no longer supported" +# if !MSVC_PREREQ(1928) +# error "MSVC versions older than Visual Studio 2019 v16.8 are no longer supported" # endif #else # define MSVC_PREREQ(version) 0 @@ -212,20 +212,6 @@ typedef size_t machine_word_t; # define NORETURN #endif -/* - * restrict - hint that writes only occur through the given pointer. - * - * Don't use MSVC's __restrict, since it has nonstandard behavior. - * Standard restrict is okay, if it is supported. - */ -#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L) -# if defined(__GNUC__) || defined(__clang__) -# define restrict __restrict__ -# else -# define restrict -# endif -#endif /* else assume 'restrict' is usable as-is */ - /* likely(expr) - hint that an expression is usually true */ #if defined(__GNUC__) || __has_builtin(__builtin_expect) # define likely(expr) __builtin_expect(!!(expr), 1) @@ -402,7 +388,8 @@ static forceinline u64 bswap64(u64 v) */ #if (defined(__GNUC__) || defined(__clang__)) && \ (defined(ARCH_X86_64) || defined(ARCH_X86_32) || \ - defined(__ARM_FEATURE_UNALIGNED) || defined(__powerpc64__) || \ + defined(__ARM_FEATURE_UNALIGNED) || \ + defined(__powerpc64__) || defined(__powerpc__) || defined(__POWERPC__) || \ defined(__riscv_misaligned_fast) || \ /* * For all compilation purposes, WebAssembly behaves like any other CPU diff --git a/vendor/libdeflate/lib/arm/cpu_features.c b/vendor/libdeflate/lib/arm/cpu_features.c index 42f81f5edf..a4008ca948 100644 --- a/vendor/libdeflate/lib/arm/cpu_features.c +++ b/vendor/libdeflate/lib/arm/cpu_features.c @@ -54,6 +54,7 @@ #include #include +#include #include #include @@ -67,7 +68,7 @@ static void scan_auxv(unsigned long *hwcap, unsigned long *hwcap2) int filled = 0; int i; - fd = open("/proc/self/auxv", O_RDONLY); + fd = open("/proc/self/auxv", O_RDONLY | O_CLOEXEC); if (fd < 0) return; @@ -130,6 +131,51 @@ static u32 query_arm_cpu_features(void) return features; } +#ifdef ARCH_ARM64 +/* + * Return whether cpu0's MIDR_EL1 identifies one of the Arm Neoverse + * V-class server cores (V1 / V2 / V3 / V3AE). MIDR_EL1 is exposed + * unprivileged via sysfs (added in Linux 4.7). Reading cpu0 only is fine + * in practice: no Neoverse V-class server SKU has shipped as part of a + * big.LITTLE cluster. Any failure (file missing, read error, parse + * failure, unrecognized CPU) returns false. + */ +static bool arm64_cpu_is_neoverse_v_class(void) +{ + int fd; + char buf[32]; + ssize_t n; + unsigned long midr; + u32 part; + + fd = open("/sys/devices/system/cpu/cpu0/regs/identification/midr_el1", + O_RDONLY | O_CLOEXEC); + if (fd < 0) + return false; + do { + n = read(fd, buf, sizeof(buf) - 1); + } while (n < 0 && errno == EINTR); + close(fd); + if (n <= 0) + return false; + buf[n] = '\0'; + midr = strtoul(buf, NULL, 0); /* sysfs prints "0x%016llx\n" */ + + /* MIDR_EL1: [31:24]=Implementer, [15:4]=PartNum. */ + if (((midr >> 24) & 0xff) != 0x41) /* Implementer must be Arm Ltd. */ + return false; + part = (midr >> 4) & 0xfff; + switch (part) { + case 0xd40: /* Neoverse V1 (e.g. AWS Graviton 3) */ + case 0xd4f: /* Neoverse V2 (e.g. AWS Graviton 4) */ + case 0xd83: /* Neoverse V3AE */ + case 0xd84: /* Neoverse V3 */ + return true; + } + return false; +} +#endif /* ARCH_ARM64 */ + #elif defined(__APPLE__) /* On Apple platforms, arm64 CPU features can be detected via sysctlbyname(). */ @@ -202,24 +248,40 @@ static const struct cpu_feature arm_cpu_feature_table[] = { {ARM_CPU_FEATURE_DOTPROD, "dotprod"}, }; +/* + * Whether to set ARM_CPU_FEATURE_PREFER_PMULL on this CPU. This is the + * right choice on CPUs whose pmull pipes have more aggregate throughput + * than the crc32 unit -- in measured cases by a wide margin: the Apple M + * series sustains ~68 GB/s on pmull vs ~25 GB/s on crc32 (M1), and the Arm + * Neoverse V class sustains ~40 GB/s vs ~22 GB/s (Graviton 4 / V2). + * + * We detect Apple at compile time, and Neoverse V-class cores at runtime + * via MIDR_EL1 on Linux. Elsewhere we leave this unset, and the dispatcher + * picks the crc32-instruction path which is the right default for most + * other modern ARM CPUs. + */ +static bool arm_cpu_prefers_pmull(void) +{ +#if defined(__APPLE__) && TARGET_OS_OSX + return true; +#elif defined(__linux__) && defined(ARCH_ARM64) + if (arm64_cpu_is_neoverse_v_class()) + return true; +#endif +#ifdef TEST_SUPPORT__DO_NOT_USE + return true; +#endif + return false; +} + volatile u32 libdeflate_arm_cpu_features = 0; void libdeflate_init_arm_cpu_features(void) { u32 features = query_arm_cpu_features(); - /* - * On the Apple M1 processor, crc32 instructions max out at about 25.5 - * GB/s in the best case of using a 3-way or greater interleaved chunked - * implementation, whereas a pmull-based implementation achieves 68 GB/s - * provided that the stride length is large enough (about 10+ vectors - * with eor3, or 12+ without). - * - * Assume that crc32 instructions are preferable in other cases. - */ -#if (defined(__APPLE__) && TARGET_OS_OSX) || defined(TEST_SUPPORT__DO_NOT_USE) - features |= ARM_CPU_FEATURE_PREFER_PMULL; -#endif + if (arm_cpu_prefers_pmull()) + features |= ARM_CPU_FEATURE_PREFER_PMULL; disable_cpu_features_for_testing(&features, arm_cpu_feature_table, ARRAY_LEN(arm_cpu_feature_table)); diff --git a/vendor/libdeflate/lib/deflate_compress.c b/vendor/libdeflate/lib/deflate_compress.c index 4a1f32769b..b24087c20c 100644 --- a/vendor/libdeflate/lib/deflate_compress.c +++ b/vendor/libdeflate/lib/deflate_compress.c @@ -3885,6 +3885,13 @@ libdeflate_alloc_compressor_ex(int compression_level, if (options->sizeof_options != sizeof(*options)) return NULL; + /* + * Note: For similarity with zlib's API, -1 is accepted as an alias for + * the default compression level. + */ + if (compression_level == -1) + compression_level = 6; + if (compression_level < 0 || compression_level > 12) return NULL; diff --git a/vendor/libdeflate/lib/deflate_decompress.c b/vendor/libdeflate/lib/deflate_decompress.c index 63726c7a50..d5af5eb024 100644 --- a/vendor/libdeflate/lib/deflate_decompress.c +++ b/vendor/libdeflate/lib/deflate_decompress.c @@ -1094,18 +1094,18 @@ typedef enum libdeflate_result (*decompress_func_t) #ifdef arch_select_decompress_func static enum libdeflate_result -dispatch_decomp(struct libdeflate_decompressor *d, - const void *in, size_t in_nbytes, - void *out, size_t out_nbytes_avail, +dispatch_decomp(struct libdeflate_decompressor * restrict d, + const void * restrict in, size_t in_nbytes, + void * restrict out, size_t out_nbytes_avail, size_t *actual_in_nbytes_ret, size_t *actual_out_nbytes_ret); static volatile decompress_func_t decompress_impl = dispatch_decomp; /* Choose the best implementation at runtime. */ static enum libdeflate_result -dispatch_decomp(struct libdeflate_decompressor *d, - const void *in, size_t in_nbytes, - void *out, size_t out_nbytes_avail, +dispatch_decomp(struct libdeflate_decompressor * restrict d, + const void * restrict in, size_t in_nbytes, + void * restrict out, size_t out_nbytes_avail, size_t *actual_in_nbytes_ret, size_t *actual_out_nbytes_ret) { decompress_func_t f = arch_select_decompress_func(); diff --git a/vendor/libdeflate/lib/x86/adler32_impl.h b/vendor/libdeflate/lib/x86/adler32_impl.h index 74c7b312b1..f1102b5e16 100644 --- a/vendor/libdeflate/lib/x86/adler32_impl.h +++ b/vendor/libdeflate/lib/x86/adler32_impl.h @@ -72,6 +72,7 @@ #endif #if (GCC_PREREQ(8, 1) || CLANG_PREREQ(6, 0, 10000000) || MSVC_PREREQ(1920)) && \ + !(CLANG_PREREQ(18, 0, 18000000) && !CLANG_PREREQ(19, 0, 19000000)) && \ !defined(LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_AVX512VNNI) /* * AVX512VNNI implementation using 256-bit vectors. This is very similar to the diff --git a/vendor/libdeflate/lib/x86/crc32_impl.h b/vendor/libdeflate/lib/x86/crc32_impl.h index 50ea52bb20..4fbdef7ebf 100644 --- a/vendor/libdeflate/lib/x86/crc32_impl.h +++ b/vendor/libdeflate/lib/x86/crc32_impl.h @@ -92,6 +92,7 @@ static const u8 MAYBE_UNUSED shift_tab[48] = { #endif #if (GCC_PREREQ(10, 1) || CLANG_PREREQ(6, 0, 10000000) || MSVC_PREREQ(1920)) && \ + !(CLANG_PREREQ(18, 0, 18000000) && !CLANG_PREREQ(19, 0, 19000000)) && \ !defined(LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_VPCLMULQDQ) /* * VPCLMULQDQ/AVX512 implementation using 256-bit vectors. This is very similar diff --git a/vendor/libdeflate/libdeflate.h b/vendor/libdeflate/libdeflate.h index d6c885f23c..1821acda8e 100644 --- a/vendor/libdeflate/libdeflate.h +++ b/vendor/libdeflate/libdeflate.h @@ -13,8 +13,8 @@ extern "C" { #endif #define LIBDEFLATE_VERSION_MAJOR 1 -#define LIBDEFLATE_VERSION_MINOR 25 -#define LIBDEFLATE_VERSION_STRING "1.25" +#define LIBDEFLATE_VERSION_MINOR 26 +#define LIBDEFLATE_VERSION_STRING "1.26" /* * Users of libdeflate.dll on Windows can define LIBDEFLATE_DLL to cause @@ -43,10 +43,11 @@ struct libdeflate_options; * level on a zlib-like scale but with a higher maximum value (1 = fastest, 6 = * medium/default, 9 = slow, 12 = slowest). Level 0 is also supported and means * "no compression", specifically "create a valid stream, but only emit - * uncompressed blocks" (this will expand the data slightly). + * uncompressed blocks" (this will expand the data slightly). Level -1 is an + * alias indicating a default level of 6. * * The return value is a pointer to the new compressor, or NULL if out of memory - * or if the compression level is invalid (i.e. outside the range [0, 12]). + * or if the compression level is invalid (i.e. outside the range [-1, 12]). * * Note: for compression, the sliding window size is defined at compilation time * to 32768, the largest size permissible in the DEFLATE format. It cannot be