Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions deps/zlib/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@ source_set("zlib_adler32_simd") {
"adler32_simd.c",
"adler32_simd.h",
]

if (!is_win || is_clang) {
cflags = [ "-mssse3" ]
}
}

if (use_arm_neon_optimizations) {
Expand Down Expand Up @@ -168,6 +164,15 @@ if (use_arm_neon_optimizations) {
}
}

# Enables 64-bit word-at-a-time compare256() in deflate's longest_match() on
# 64-bit little-endian architectures (x64 and arm64). Follows the same pattern
# as INFLATE_CHUNK_READ_64LE and DEFLATE_CHUNK_WRITE_64LE below.
config("zlib_compare256_config") {
if (current_cpu == "x64" || current_cpu == "arm64") {
defines = [ "DEFLATE_COMPARE256_64LE" ]
}
}

config("zlib_data_chunk_simd_config") {
if (use_x86_x64_optimizations) {
defines = [ "INFLATE_CHUNK_SIMD_SSE2" ]
Expand Down Expand Up @@ -234,13 +239,6 @@ source_set("zlib_crc32_simd") {
"crc32_simd.h",
"crc_folding.c",
]

if (!is_win || is_clang) {
cflags = [
"-msse4.2",
"-mpclmul",
]
}
}

configs += [ ":zlib_internal_config" ]
Expand Down Expand Up @@ -296,6 +294,7 @@ component("zlib") {
sources = [
"adler32.c",
"chromeconf.h",
"compare256.h",
"compress.c",
"contrib/optimizations/insert_string.h",
"cpu_features.c",
Expand Down Expand Up @@ -370,6 +369,7 @@ component("zlib") {
public_configs = [ ":zlib_config" ]

configs += [
":zlib_compare256_config",
":zlib_internal_config",

# Must be after no_chromium_code for warning flags to be ordered correctly.
Expand Down
5 changes: 2 additions & 3 deletions deps/zlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,14 @@ if (ENABLE_SIMD_OPTIMIZATIONS)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")

if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
add_definitions(-DDEFLATE_COMPARE256_64LE)
add_definitions(-DINFLATE_CHUNK_SIMD_SSE2)
add_definitions(-DADLER32_SIMD_SSSE3)
add_definitions(-DINFLATE_CHUNK_READ_64LE)
add_definitions(-DDEFLATE_CHUNK_WRITE_64LE)
add_definitions(-DCRC32_SIMD_SSE42_PCLMUL)
if (ENABLE_SIMD_AVX512)
add_definitions(-DCRC32_SIMD_AVX512_PCLMUL)
add_compile_options(-mvpclmulqdq -msse2 -mavx512f -mpclmul)
else()
add_compile_options(-msse4.2 -mpclmul)
endif()
add_definitions(-DDEFLATE_SLIDE_HASH_SSE2)
# Required by CPU features detection code.
Expand All @@ -118,6 +116,7 @@ if (ENABLE_SIMD_OPTIMIZATIONS)
add_definitions(-DDEFLATE_CHUNK_WRITE_64LE)
add_definitions(-DCRC32_ARMV8_CRC32)
add_definitions(-DDEFLATE_SLIDE_HASH_NEON)
add_definitions(-DDEFLATE_COMPARE256_64LE)
# Required by CPU features detection code.
if (APPLE)
add_definitions(-DARMV8_OS_MACOS)
Expand Down
2 changes: 1 addition & 1 deletion deps/zlib/adler32_simd.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

#include <tmmintrin.h>

#if defined(__GNUC__)
#if defined(__GNUC__) || defined(__clang__)
__attribute__((__target__("ssse3")))
#endif
uint32_t ZLIB_INTERNAL adler32_simd_( /* SSSE3 */
Expand Down
56 changes: 56 additions & 0 deletions deps/zlib/compare256.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* compare256.h
*
* This does 256-byte match comparison for deflate's longest_match.
*
* Copyright 2026 The Chromium Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the Chromium source repository LICENSE file.
*/
#ifndef COMPARE256_H
#define COMPARE256_H

#include <stdint.h>
#include <string.h>
#if defined(_MSC_VER) && !defined(__clang__)
#include <intrin.h>
#endif

/* Safe unaligned 16-bit load. Compilers optimize this into a single load
* instruction. */
static inline uint16_t read16(const void* p) {
uint16_t v;
memcpy(&v, p, sizeof(v));
return v;
}

/* Finds the byte offset (0..7) of the first difference in non-zero XOR mask
* `x`:
*/
static inline int compare256_diff(uint64_t x) {
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long i;
_BitScanForward64(&i, x);
return (int)i / 8;
#else
return __builtin_ctzll(x) / 8;
#endif
}

/* Returns the number of matching leading bytes (0 to 256) between src0 and
* src1. Compares 8 bytes per iteration with early exit. */
static inline int compare256(const unsigned char* src0,
const unsigned char* src1) {
int len = 0;
do {
uint64_t a, b, x;
memcpy(&a, src0 + len, sizeof(a));
memcpy(&b, src1 + len, sizeof(b));
x = a ^ b;
if (x)
return len + compare256_diff(x);
len += (int)sizeof(a);
} while (len < 256);
return 256;
}

#endif /* COMPARE256_H */
37 changes: 37 additions & 0 deletions deps/zlib/contrib/tests/utils_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,17 @@
#include "third_party/zlib/contrib/minizip/zip.h"
#endif

#include "compare256.h"
#include "zlib.h"

// Some tests are for little endian optimizations and should be skipped if
// running on big endian.
#if !defined(__BYTE_ORDER__) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define ZLIB_TEST_LITTLE_ENDIAN 1
#else
#define ZLIB_TEST_LITTLE_ENDIAN 0
#endif

void TestPayloads(size_t input_size, zlib_internal::WrapperType type,
const int compression_level = Z_DEFAULT_COMPRESSION) {
std::vector<unsigned char> input;
Expand Down Expand Up @@ -1475,4 +1484,32 @@ TEST(ZlibTest, Crbug500521311) {
EXPECT_EQ(unzClose(uzf), UNZ_OK);
}

// compare256() returns the number of equal leading bytes. The buffers are
// exactly the 256 bytes it may read, so ASan traps any over-read.
TEST(ZlibTest, Compare256) {
if (!ZLIB_TEST_LITTLE_ENDIAN) {
GTEST_SKIP() << "compare256() is little-endian only";
}
for (int equal = 0; equal <= 256; ++equal) {
std::vector<unsigned char> a(256, 'a'), b(256, 'a');
if (equal < 256)
b[equal] = 'b';
EXPECT_EQ(compare256(a.data(), b.data()), equal);
}
}

// longest_match() computes 2 + compare256(scan + 2, match + 2), the first two
// bytes being known equal, so a match must still reach MAX_MATCH (258).
TEST(ZlibTest, Compare256ReachesMaxMatch) {
if (!ZLIB_TEST_LITTLE_ENDIAN) {
GTEST_SKIP() << "compare256() is little-endian only";
}
for (int match_len = 250; match_len <= 258; ++match_len) {
std::vector<unsigned char> a(258, 'a'), b(258, 'a');
if (match_len < 258)
b[match_len] = 'b';
EXPECT_EQ(2 + compare256(a.data() + 2, b.data() + 2), match_len);
}
}

#endif
5 changes: 5 additions & 0 deletions deps/zlib/cpu_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ static void _cpu_check_features(void)
#include <immintrin.h>
#include <xsaveintrin.h>
#endif
/* _xgetbv() below needs the xsave ISA. Annotate it here so the build does not
* need -mxsave. */
#if defined(CRC32_SIMD_AVX512_PCLMUL) && (defined(__GNUC__) || defined(__clang__))
__attribute__((__target__("xsave")))
#endif
static void _cpu_check_features(void)
{
int x86_cpu_has_sse2;
Expand Down
6 changes: 6 additions & 0 deletions deps/zlib/crc32_simd.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include <wmmintrin.h>
#include <immintrin.h>

#if defined(__GNUC__) || defined(__clang__)
__attribute__((__target__("avx512f,avx512vl,vpclmulqdq")))
#endif
uint32_t ZLIB_INTERNAL crc32_avx512_simd_( /* AVX512+PCLMUL */
const unsigned char *buf,
z_size_t len,
Expand Down Expand Up @@ -212,6 +215,9 @@ uint32_t ZLIB_INTERNAL crc32_avx512_simd_( /* AVX512+PCLMUL */
#include <smmintrin.h>
#include <wmmintrin.h>

#if defined(__GNUC__) || defined(__clang__)
__attribute__((__target__("sse4.2,pclmul")))
#endif
uint32_t ZLIB_INTERNAL crc32_sse42_simd_( /* SSE4.2+PCLMUL */
const unsigned char *buf,
z_size_t len,
Expand Down
14 changes: 14 additions & 0 deletions deps/zlib/crc_folding.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
#include <immintrin.h>
#include <wmmintrin.h>

#if defined(__GNUC__) || defined(__clang__)
#define TARGET_SSE42_PCLMUL __attribute__((__target__("sse4.2,pclmul")))
#else
#define TARGET_SSE42_PCLMUL
#endif

#define CRC_LOAD(s) \
do { \
__m128i xmm_crc0 = _mm_loadu_si128((__m128i *)s->crc0 + 0);\
Expand All @@ -41,6 +47,7 @@
_mm_storeu_si128((__m128i *)s->crc0 + 4, xmm_crc_part);\
} while (0);

TARGET_SSE42_PCLMUL
ZLIB_INTERNAL void crc_fold_init(deflate_state *const s)
{
CRC_LOAD(s)
Expand All @@ -55,6 +62,7 @@ ZLIB_INTERNAL void crc_fold_init(deflate_state *const s)
s->strm->adler = 0;
}

TARGET_SSE42_PCLMUL
local void fold_1(deflate_state *const s,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3)
Expand All @@ -81,6 +89,7 @@ local void fold_1(deflate_state *const s,
*xmm_crc3 = _mm_castps_si128(ps_res);
}

TARGET_SSE42_PCLMUL
local void fold_2(deflate_state *const s,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3)
Expand Down Expand Up @@ -115,6 +124,7 @@ local void fold_2(deflate_state *const s,
*xmm_crc3 = _mm_castps_si128(ps_res31);
}

TARGET_SSE42_PCLMUL
local void fold_3(deflate_state *const s,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3)
Expand Down Expand Up @@ -155,6 +165,7 @@ local void fold_3(deflate_state *const s,
*xmm_crc3 = _mm_castps_si128(ps_res32);
}

TARGET_SSE42_PCLMUL
local void fold_4(deflate_state *const s,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3)
Expand Down Expand Up @@ -221,6 +232,7 @@ local const unsigned zalign(32) pshufb_shf_table[60] = {
0x0201008f,0x06050403,0x0a090807,0x0e0d0c0b /* shl 1 (16 -15)/shr15*/
};

TARGET_SSE42_PCLMUL
local void partial_fold(deflate_state *const s, const size_t len,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3,
Expand Down Expand Up @@ -271,6 +283,7 @@ local void partial_fold(deflate_state *const s, const size_t len,
*xmm_crc3 = _mm_castps_si128(ps_res);
}

TARGET_SSE42_PCLMUL
ZLIB_INTERNAL void crc_fold_copy(deflate_state *const s,
unsigned char *dst, const unsigned char *src, long len)
{
Expand Down Expand Up @@ -427,6 +440,7 @@ local const unsigned zalign(16) crc_mask2[4] = {
0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
};

TARGET_SSE42_PCLMUL
unsigned ZLIB_INTERNAL crc_fold_512to32(deflate_state *const s)
{
const __m128i xmm_mask = _mm_load_si128((__m128i *)crc_mask);
Expand Down
22 changes: 19 additions & 3 deletions deps/zlib/deflate.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
#include "slide_hash_simd.h"
#endif

#include "compare256.h"

#if defined(QAT_COMPRESSION_ENABLED)
#include "contrib/qat/deflate_qat.h"
#endif
Expand Down Expand Up @@ -1492,7 +1494,13 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
Posf *prev = s->prev;
uInt wmask = s->w_mask;

#ifdef UNALIGNED_OK
#if defined(DEFLATE_COMPARE256_64LE)
/* Quickly reject non-matches with the 2-byte prefilter
* (scan_start/scan_end); candidates that pass are extended 8 bytes at a
* time with compare256(). */
uInt scan_start = read16(scan);
uInt scan_end = read16(scan + best_len - 1);
#elif defined(UNALIGNED_OK)
/* Compare two bytes at a time. Note: this is not always beneficial.
* Try with and without -DUNALIGNED_OK to check.
*/
Expand Down Expand Up @@ -1534,7 +1542,13 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
* However the length of the match is limited to the lookahead, so
* the output of deflate is not affected by the uninitialized values.
*/
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
#if defined(DEFLATE_COMPARE256_64LE)
if (read16(match + best_len - 1) != scan_end ||
read16(match) != scan_start) continue;
/* scan_start matched, so bytes 0..1 are equal; compare the remaining
* up to 256 bytes so the length can still reach MAX_MATCH (258). */
len = 2 + compare256(scan + 2, match + 2);
#elif (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use
* UNALIGNED_OK if your compiler uses a different size.
*/
Expand Down Expand Up @@ -1624,7 +1638,9 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
s->match_start = cur_match;
best_len = len;
if (len >= nice_match) break;
#ifdef UNALIGNED_OK
#if defined(DEFLATE_COMPARE256_64LE)
scan_end = read16(scan + best_len - 1);
#elif defined(UNALIGNED_OK)
scan_end = *(ushf*)(scan + best_len - 1);
#else
scan_end1 = scan[best_len - 1];
Expand Down
2 changes: 1 addition & 1 deletion src/zlib_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// Refer to tools/dep_updaters/update-zlib.sh
#ifndef SRC_ZLIB_VERSION_H_
#define SRC_ZLIB_VERSION_H_
#define ZLIB_VERSION "1.3.2.1-motley-8002e91"
#define ZLIB_VERSION "1.3.2.1-motley-5eb4d7e"
#endif // SRC_ZLIB_VERSION_H_
Loading