]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Compute w_bits rather than storing it in the deflate_state structure
authorNathan Moinvaziri <nathan@nathanm.com>
Mon, 8 Dec 2025 03:59:36 +0000 (19:59 -0800)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Tue, 9 Dec 2025 14:23:33 +0000 (15:23 +0100)
Co-authored-by: Brian Pane <brianp@brianp.net>
arch/s390/dfltcc_deflate.c
deflate.c
deflate.h
test/benchmarks/benchmark_insert_string.cc

index f602b44be46190da409ac975ee649950ccf703df..8ec3146cbced9148901fea10b4d1b59cf09925fb 100644 (file)
@@ -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 */
index 1002fa6eba2a7f2f8d26406c89dd8f171fb6376e..8aa693551884f103b9b943df73108431d39088a6 100644 (file)
--- 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;
 
index 9cd0fe8f66a5200cd0efd21c2e202d1676485e8b..fb6f7cd1ea228dfbf3c67f7bc13d60587240c7de 100644 (file)
--- 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 */
index 7a68fb51929eda325513d03a27936b07a50540c9..a793b795d11848f8a5b13e51495a9b312dab42dc 100644 (file)
@@ -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