From: Dougall Johnson Date: Mon, 22 Aug 2022 01:39:35 +0000 (+1000) Subject: Inflate: refill unconditionally X-Git-Tag: 2.1.0-beta1~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cebd4721153aa813252a8c862d9c97ccf529509;p=thirdparty%2Fzlib-ng.git Inflate: refill unconditionally --- diff --git a/inffast_tpl.h b/inffast_tpl.h index e17e59241..c209021b9 100644 --- a/inffast_tpl.h +++ b/inffast_tpl.h @@ -145,14 +145,22 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) { window is overwritten then future matches with far distances will fail to copy correctly. */ extra_safe = (wsize != 0 && out >= window && out + INFLATE_FAST_MIN_LEFT <= window + wsize); + /* This is extremely latency sensitive, so empty inline assembly blocks are + used to prevent the compiler from reassociating. */ +#define REFILL() do { \ + hold |= load_64_bits(in, bits); \ + in += 7; \ + __asm__ volatile ("" : "+r"(in)); \ + uint64_t tmp = ((bits >> 3) & 7); \ + __asm__ volatile ("" : "+r"(tmp)); \ + in -= tmp; \ + bits |= 56; \ + } while (0) + /* decode literals and length/distances until end-of-block or not enough input data or output space */ do { - if (bits < MAX_BITS) { - hold |= load_64_bits(in, bits); - in += 6; - bits += 48; - } + REFILL(); here = lcode + (hold & lmask); dolen: DROPBITS(here->bits); @@ -164,20 +172,10 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) { *out++ = (unsigned char)(here->val); } else if (op & 16) { /* length base */ len = here->val; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold |= load_64_bits(in, bits); - in += 6; - bits += 48; - } + op &= MAX_BITS; /* number of extra bits */ len += BITS(op); DROPBITS(op); Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < MAX_BITS) { - hold |= load_64_bits(in, bits); - in += 6; - bits += 48; - } here = dcode + (hold & dmask); dodist: DROPBITS(here->bits); @@ -185,11 +183,6 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) { if (op & 16) { /* distance base */ dist = here->val; op &= MAX_BITS; /* number of extra bits */ - if (bits < op) { - hold |= load_64_bits(in, bits); - in += 6; - bits += 48; - } dist += BITS(op); #ifdef INFLATE_STRICT if (dist > dmax) {