]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Inflate: add fast-path for literals
authorDougall Johnson <dougallj@gmail.com>
Mon, 22 Aug 2022 01:44:41 +0000 (11:44 +1000)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Fri, 24 Feb 2023 12:24:49 +0000 (13:24 +0100)
inffast_tpl.h
inflate_p.h
zutil.h

index c209021b92e4e81c1e0df52f01c5c37aa8340a97..9ddd187d84731ca741d7dcca1516d40d2d2da33e 100644 (file)
@@ -145,15 +145,10 @@ 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; \
+        in -= ((bits >> 3) & 7); \
         bits |= 56; \
     } while (0)
 
@@ -162,6 +157,16 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) {
     do {
         REFILL();
         here = lcode + (hold & lmask);
+        if (here->op == 0) {
+            *out++ = (unsigned char)(here->val);
+            DROPBITS(here->bits);
+            here = lcode + (hold & lmask);
+            if (here->op == 0) {
+                *out++ = (unsigned char)(here->val);
+                DROPBITS(here->bits);
+                here = lcode + (hold & lmask);
+            }
+        }
       dolen:
         DROPBITS(here->bits);
         op = here->op;
@@ -177,6 +182,9 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) {
             DROPBITS(op);
             Tracevv((stderr, "inflate:         length %u\n", len));
             here = dcode + (hold & dmask);
+            if (bits < MAX_BITS + MAX_DIST_EXTRA_BITS) {
+                REFILL();
+            }
           dodist:
             DROPBITS(here->bits);
             op = here->op;
index 2b57b317e7ae51a3ebca1978439fef212fac4f67..a007cd05df199cbd77865c54b2471349550adc1a 100644 (file)
         strm->msg = (char *)errmsg; \
     } while (0)
 
-#define INFLATE_FAST_MIN_HAVE 8
-#define INFLATE_FAST_MIN_LEFT 258
+#define INFLATE_FAST_MIN_HAVE 15
+#define INFLATE_FAST_MIN_LEFT 260
 
 /* Load 64 bits from IN and place the bytes at offset BITS in the result. */
 static inline uint64_t load_64_bits(const unsigned char *in, unsigned bits) {
diff --git a/zutil.h b/zutil.h
index 7b9a8b09424df8f5f1c75795331821878dc7a7ce..663616b44d89ebfcdb5fa424945828d6edfe8834 100644 (file)
--- a/zutil.h
+++ b/zutil.h
@@ -38,6 +38,8 @@ extern z_const char * const PREFIX(z_errmsg)[10]; /* indexed by 2-zlib_error */
 
 #define MAX_BITS 15
 /* all codes must not exceed MAX_BITS bits */
+#define MAX_DIST_EXTRA_BITS 13
+/* maximum number of extra distance bits */
 
 #if MAX_MEM_LEVEL >= 8
 #  define DEF_MEM_LEVEL 8