summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Moinvaziri <nathan@nathanm.com>2025-12-07 19:59:36 -0800
committerHans Kristian Rosbach <hk-github@circlestorm.org>2025-12-09 15:23:33 +0100
commitb9aeb4aa2a811ee1eb0e5f827e3d3f29da4ad62a (patch)
tree2488e5410ed5ed32a00d4585b3be0c18a5450c9c
parent2c7fbfba2f19f87c7920a18ab6a69fa9675bd56a (diff)
downloadProject-Tick-b9aeb4aa2a811ee1eb0e5f827e3d3f29da4ad62a.tar.gz
Project-Tick-b9aeb4aa2a811ee1eb0e5f827e3d3f29da4ad62a.zip
Compute w_bits rather than storing it in the deflate_state structure
Co-authored-by: Brian Pane <brianp@brianp.net>
-rw-r--r--arch/s390/dfltcc_deflate.c4
-rw-r--r--deflate.c9
-rw-r--r--deflate.h24
-rw-r--r--test/benchmarks/benchmark_insert_string.cc1
4 files changed, 29 insertions, 9 deletions
diff --git a/arch/s390/dfltcc_deflate.c b/arch/s390/dfltcc_deflate.c
index f602b44be4..8ec3146cbc 100644
--- a/arch/s390/dfltcc_deflate.c
+++ b/arch/s390/dfltcc_deflate.c
@@ -60,7 +60,7 @@ static inline int dfltcc_can_deflate_with_params(PREFIX3(streamp) strm, int leve
int Z_INTERNAL PREFIX(dfltcc_can_deflate)(PREFIX3(streamp) strm) {
deflate_state *state = (deflate_state *)strm->state;
- return dfltcc_can_deflate_with_params(strm, state->level, state->w_bits, state->strategy, state->reproducible);
+ return dfltcc_can_deflate_with_params(strm, state->level, W_BITS(state), state->strategy, state->reproducible);
}
static inline void dfltcc_gdht(PREFIX3(streamp) strm) {
@@ -319,7 +319,7 @@ static int dfltcc_was_deflate_used(PREFIX3(streamp) strm) {
int Z_INTERNAL PREFIX(dfltcc_deflate_params)(PREFIX3(streamp) strm, int level, int strategy, int *flush) {
deflate_state *state = (deflate_state *)strm->state;
int could_deflate = PREFIX(dfltcc_can_deflate)(strm);
- int can_deflate = dfltcc_can_deflate_with_params(strm, level, state->w_bits, strategy, state->reproducible);
+ int can_deflate = dfltcc_can_deflate_with_params(strm, level, W_BITS(state), strategy, state->reproducible);
if (can_deflate == could_deflate)
/* We continue to work in the same mode - no changes needed */
diff --git a/deflate.c b/deflate.c
index 1002fa6eba..8aa6935518 100644
--- a/deflate.c
+++ b/deflate.c
@@ -302,8 +302,7 @@ int32_t ZNG_CONDEXPORT PREFIX(deflateInit2)(PREFIX3(stream) *strm, int32_t level
s->wrap = wrap;
s->gzhead = NULL;
- s->w_bits = (unsigned int)windowBits;
- s->w_size = 1 << s->w_bits;
+ s->w_size = 1 << windowBits;
s->high_water = 0; /* nothing written to s->window yet */
@@ -724,7 +723,7 @@ unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long
/* if not default parameters, return conservative bound */
if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) || /* hook for IBM Z DFLTCC */
- s->w_bits != MAX_WBITS || HASH_BITS < 15) {
+ W_BITS(s) != MAX_WBITS || HASH_BITS < 15) {
if (s->level == 0) {
/* upper bound for stored blocks with length 127 (memLevel == 1) --
~4% overhead plus a small constant */
@@ -814,7 +813,7 @@ int32_t Z_EXPORT PREFIX(deflate)(PREFIX3(stream) *strm, int32_t flush) {
s->status = BUSY_STATE;
if (s->status == INIT_STATE) {
/* zlib header */
- unsigned int header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ unsigned int header = (Z_DEFLATED + ((W_BITS(s)-8)<<4)) << 8;
unsigned int level_flags;
if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
@@ -1086,7 +1085,7 @@ int32_t Z_EXPORT PREFIX(deflateCopy)(PREFIX3(stream) *dest, PREFIX3(stream) *sou
memcpy((void *)dest, (void *)source, sizeof(PREFIX3(stream)));
- deflate_allocs *alloc_bufs = alloc_deflate(dest, ss->w_bits, ss->lit_bufsize);
+ deflate_allocs *alloc_bufs = alloc_deflate(dest, W_BITS(ss), ss->lit_bufsize);
if (alloc_bufs == NULL)
return Z_MEM_ERROR;
diff --git a/deflate.h b/deflate.h
index 9cd0fe8f66..fb6f7cd1ea 100644
--- a/deflate.h
+++ b/deflate.h
@@ -155,7 +155,6 @@ struct ALIGNED_(64) internal_state {
/* used by deflate.c: */
unsigned int w_size; /* LZ77 window size (32K by default) */
- unsigned int w_bits; /* log2(w_size) (8..16) */
unsigned int lookahead; /* number of valid bytes ahead in window */
unsigned int high_water;
@@ -406,6 +405,29 @@ static inline void put_uint64(deflate_state *s, uint64_t lld) {
#define W_MASK(s) ((s)->w_size - 1)
/* Window mask: w_size is always a power of 2, so w_mask = w_size - 1 */
+#ifdef HAVE_BUILTIN_CTZ
+# define W_BITS(s) ((unsigned int)__builtin_ctz((s)->w_size))
+#else
+/* Fallback for w_size which is always a power of 2 between 256 and 32768 */
+static inline unsigned int compute_w_bits(unsigned int w_size) {
+ /* Switch ordered by likelihood - most common first (MAX_WBITS=15 -> 32768) */
+ switch (w_size) {
+ case 32768: return 15; /* MAX_WBITS default */
+ case 16384: return 14;
+ case 8192: return 13;
+ case 4096: return 12;
+ case 2048: return 11;
+ case 1024: return 10;
+ case 512: return 9;
+ case 256: return 8;
+ }
+ Assert(w_size >= 256 && w_size <= 32768, "invalid w_size");
+ return 0;
+}
+# define W_BITS(s) compute_w_bits((s)->w_size)
+#endif
+/* Window bits: log2(w_size), computed from w_size since w_size is a power of 2 */
+
#define WIN_INIT STD_MAX_MATCH
/* Number of bytes after end of data in window to initialize in order to avoid
memory checker errors from longest match routines */
diff --git a/test/benchmarks/benchmark_insert_string.cc b/test/benchmarks/benchmark_insert_string.cc
index 7a68fb5192..a793b795d1 100644
--- a/test/benchmarks/benchmark_insert_string.cc
+++ b/test/benchmarks/benchmark_insert_string.cc
@@ -34,7 +34,6 @@ public:
// Set up window parameters
s->w_size = MAX_WSIZE;
- s->w_bits = 15;
s->window_size = TEST_WINDOW_SIZE;
// Allocate window