]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Revert "DFLTCC update for window optimization from Jim & Nathan"
authorNathan Moinvaziri <nathan@nathanm.com>
Mon, 7 Mar 2022 03:16:37 +0000 (19:16 -0800)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Wed, 23 Mar 2022 10:30:35 +0000 (11:30 +0100)
This reverts commit b4ca25afabba7b4bf74d36e26728006d28df891d.

arch/s390/README.md
arch/s390/dfltcc_deflate.c
arch/s390/dfltcc_detail.h
arch/s390/dfltcc_inflate.c
arch/s390/dfltcc_inflate.h
inflate.c
inflate_p.h

index b4b3fb8b51fc15c1ecf65f9f960796ac60a20ed4..90066f0f96f0d61cb60e5267fc00983a1e2315fe 100644 (file)
@@ -66,10 +66,11 @@ buffer and a window. `ZALLOC_STATE()`, `ZFREE_STATE()`, `ZCOPY_STATE()`,
 details for the parameter block (which is allocated alongside zlib-ng
 state) and the window (which must be page-aligned).
 
-Software and hardware deflate window formats don't match, therefore,
-`deflateSetDictionary()` and `deflateGetDictionary()` need special handling,
-which is triggered using `DEFLATE_SET_DICTIONARY_HOOK()` and
-`DEFLATE_GET_DICTIONARY_HOOK()` macros.
+While inflate software and hardware window formats match, this is not
+the case for deflate. Therefore, `deflateSetDictionary()` and
+`deflateGetDictionary()` need special handling, which is triggered using
+`DEFLATE_SET_DICTIONARY_HOOK()` and `DEFLATE_GET_DICTIONARY_HOOK()`
+macros.
 
 `deflateResetKeep()` and `inflateResetKeep()` update the DFLTCC
 parameter block using `DEFLATE_RESET_KEEP_HOOK()` and
@@ -91,14 +92,9 @@ and `DEFLATE_NEED_CONSERVATIVE_BOUND()` macros make `deflateBound()`
 return the correct results for the hardware implementation.
 
 Actual compression and decompression are handled by `DEFLATE_HOOK()` and
-`INFLATE_TYPEDO_HOOK()` macros.
-
-Software and hardware inflate window formats don't match, therefore,
-`inflateSetDictionary()` and `inflateGetDictionary()` need special handling,
-which is triggered using `INFLATE_SET_DICTIONARY_HOOK()` and
-`INFLATE_GET_DICTIONARY_HOOK()` macros. Furthermore, calling
-`window_output_flush()` is suppressed using
-`INFLATE_NEED_WINDOW_OUTPUT_FLUSH()` macro.
+`INFLATE_TYPEDO_HOOK()` macros. Since inflation with DFLTCC manages the
+window on its own, calling `updatewindow()` is suppressed using
+`INFLATE_NEED_UPDATEWINDOW()` macro.
 
 In addition to compression, DFLTCC computes CRC-32 and Adler-32
 checksums, therefore, whenever it's used, software checksumming is
index c498e3ecaff01e6c9f5092392b1b35e0bf033483..dcb3f7c5d73ebe55edb600b37c371a0027136503 100644 (file)
@@ -342,13 +342,46 @@ int Z_INTERNAL dfltcc_can_set_reproducible(PREFIX3(streamp) strm, int reproducib
     return reproducible != state->reproducible && !dfltcc_was_deflate_used(strm);
 }
 
+/*
+   Preloading history.
+*/
+static void append_history(struct dfltcc_param_v0 *param, unsigned char *history, const unsigned char *buf, uInt count) {
+    size_t offset;
+    size_t n;
+
+    /* Do not use more than 32K */
+    if (count > HB_SIZE) {
+        buf += count - HB_SIZE;
+        count = HB_SIZE;
+    }
+    offset = (param->ho + param->hl) % HB_SIZE;
+    if (offset + count <= HB_SIZE)
+        /* Circular history buffer does not wrap - copy one chunk */
+        memcpy(history + offset, buf, count);
+    else {
+        /* Circular history buffer wraps - copy two chunks */
+        n = HB_SIZE - offset;
+        memcpy(history + offset, buf, n);
+        memcpy(history, buf + n, count - n);
+    }
+    n = param->hl + count;
+    if (n <= HB_SIZE)
+        /* All history fits into buffer - no need to discard anything */
+        param->hl = n;
+    else {
+        /* History does not fit into buffer - discard extra bytes */
+        param->ho = (param->ho + (n - HB_SIZE)) % HB_SIZE;
+        param->hl = HB_SIZE;
+    }
+}
+
 int Z_INTERNAL dfltcc_deflate_set_dictionary(PREFIX3(streamp) strm,
                                                 const unsigned char *dictionary, uInt dict_length) {
     deflate_state *state = (deflate_state *)strm->state;
     struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
     struct dfltcc_param_v0 *param = &dfltcc_state->param;
 
-    dfltcc_append_history(param, state->window, dictionary, dict_length);
+    append_history(param, state->window, dictionary, dict_length);
     state->strstart = 1; /* Add FDICT to zlib header */
     state->block_start = state->strstart; /* Make deflate_stored happy */
     return Z_OK;
@@ -359,6 +392,17 @@ int Z_INTERNAL dfltcc_deflate_get_dictionary(PREFIX3(streamp) strm, unsigned cha
     struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
     struct dfltcc_param_v0 *param = &dfltcc_state->param;
 
-    dfltcc_get_history(param, state->window, dictionary, dict_length);
+    if (dictionary) {
+        if (param->ho + param->hl <= HB_SIZE)
+            /* Circular history buffer does not wrap - copy one chunk */
+            memcpy(dictionary, state->window + param->ho, param->hl);
+        else {
+            /* Circular history buffer wraps - copy two chunks */
+            memcpy(dictionary, state->window + param->ho, HB_SIZE - param->ho);
+            memcpy(dictionary + HB_SIZE - param->ho, state->window, param->ho + param->hl - HB_SIZE);
+        }
+    }
+    if (dict_length)
+        *dict_length = param->hl;
     return Z_OK;
 }
index 5fb8f47c52f70108fdd3a3be109ab102b82ba50b..4ec03f8097dc650b80086ae91bc9a21c9f4eb1eb 100644 (file)
@@ -197,50 +197,3 @@ struct dfltcc_state {
 #define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1))
 
 #define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8)))
-
-static inline void dfltcc_get_history(struct dfltcc_param_v0 *param, const unsigned char *history,
-                                         unsigned char *buf, uInt *count) {
-    if (buf) {
-        if (param->ho + param->hl <= HB_SIZE)
-            /* Circular history buffer does not wrap - copy one chunk */
-            memcpy(buf, history + param->ho, param->hl);
-        else {
-            /* Circular history buffer wraps - copy two chunks */
-            memcpy(buf, history + param->ho, HB_SIZE - param->ho);
-            memcpy(buf + HB_SIZE - param->ho, history, param->ho + param->hl - HB_SIZE);
-        }
-    }
-    if (count)
-        *count = param->hl;
-}
-
-static inline void dfltcc_append_history(struct dfltcc_param_v0 *param, unsigned char *history,
-                                            const unsigned char *buf, uInt count) {
-    size_t offset;
-    size_t n;
-
-    /* Do not use more than 32K */
-    if (count > HB_SIZE) {
-        buf += count - HB_SIZE;
-        count = HB_SIZE;
-    }
-    offset = (param->ho + param->hl) % HB_SIZE;
-    if (offset + count <= HB_SIZE)
-        /* Circular history buffer does not wrap - copy one chunk */
-        memcpy(history + offset, buf, count);
-    else {
-        /* Circular history buffer wraps - copy two chunks */
-        n = HB_SIZE - offset;
-        memcpy(history + offset, buf, n);
-        memcpy(history, buf + n, count - n);
-    }
-    n = param->hl + count;
-    if (n <= HB_SIZE)
-        /* All history fits into buffer - no need to discard anything */
-        param->hl = n;
-    else {
-        /* History does not fit into buffer - discard extra bytes */
-        param->ho = (param->ho + (n - HB_SIZE)) % HB_SIZE;
-        param->hl = HB_SIZE;
-    }
-}
index 9b1497d2b866b526dc59150d8660740f72668be0..253506466d80f828da9e5a60605e42e539a471ed 100644 (file)
@@ -83,6 +83,8 @@ dfltcc_inflate_action Z_INTERNAL dfltcc_inflate(PREFIX3(streamp) strm, int flush
     /* Translate stream to parameter block */
     param->cvt = state->flags ? CVT_CRC32 : CVT_ADLER32;
     param->sbb = state->bits;
+    param->hl = state->whave; /* Software and hardware history formats match */
+    param->ho = (state->wnext - state->whave) & ((1 << HB_BITS) - 1);
     if (param->hl)
         param->nt = 0; /* Honor history for the first block */
     param->cv = state->flags ? ZSWAP32(state->check) : state->check;
@@ -96,6 +98,8 @@ dfltcc_inflate_action Z_INTERNAL dfltcc_inflate(PREFIX3(streamp) strm, int flush
     strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
     state->last = cc == DFLTCC_CC_OK;
     state->bits = param->sbb;
+    state->whave = param->hl;
+    state->wnext = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
     state->check = state->flags ? ZSWAP32(param->cv) : param->cv;
     if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
         /* Report an error if stream is corrupted */
@@ -118,8 +122,6 @@ int Z_INTERNAL dfltcc_was_inflate_used(PREFIX3(streamp) strm) {
 int Z_INTERNAL dfltcc_inflate_disable(PREFIX3(streamp) strm) {
     struct inflate_state *state = (struct inflate_state *)strm->state;
     struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
-    struct dfltcc_param_v0 *param = &dfltcc_state->param;
-    uInt count;
 
     if (!dfltcc_can_inflate(strm))
         return 0;
@@ -131,29 +133,5 @@ int Z_INTERNAL dfltcc_inflate_disable(PREFIX3(streamp) strm) {
         return 1;
     /* DFLTCC was not used yet - decompress in software */
     memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
-    /* Convert window from hardware to software format. Use its second part as scratch space. */
-    dfltcc_get_history(param, state->window, state->window + state->wsize, &count);
-    state->whave = count;
-    state->wnext = 0;
-    memcpy(state->window + state->wsize - state->whave, state->window + state->wsize, state->whave);
     return 0;
 }
-
-int Z_INTERNAL dfltcc_inflate_set_dictionary(PREFIX3(streamp) strm, const unsigned char *dictionary, uInt dict_length) {
-    struct inflate_state *state = (struct inflate_state *)strm->state;
-    struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
-    struct dfltcc_param_v0 *param = &dfltcc_state->param;
-
-    dfltcc_append_history(param, state->window, dictionary, dict_length);
-    state->havedict = 1;
-    return Z_OK;
-}
-
-int Z_INTERNAL dfltcc_inflate_get_dictionary(PREFIX3(streamp) strm, unsigned char *dictionary, uInt *dict_length) {
-    struct inflate_state *state = (struct inflate_state *)strm->state;
-    struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
-    struct dfltcc_param_v0 *param = &dfltcc_state->param;
-
-    dfltcc_get_history(param, state->window, dictionary, dict_length);
-    return Z_OK;
-}
index 4b68b7048e3d28cc737c1c2d57278c8a2a4b7da8..fc8a000f7b9383af15aa7e3cee3b384e563fae7d 100644 (file)
@@ -12,8 +12,6 @@ typedef enum {
 dfltcc_inflate_action Z_INTERNAL dfltcc_inflate(PREFIX3(streamp) strm, int flush, int *ret);
 int Z_INTERNAL dfltcc_was_inflate_used(PREFIX3(streamp) strm);
 int Z_INTERNAL dfltcc_inflate_disable(PREFIX3(streamp) strm);
-int Z_INTERNAL dfltcc_inflate_set_dictionary(PREFIX3(streamp) strm, const unsigned char *dictionary, uInt dict_length);
-int Z_INTERNAL dfltcc_inflate_get_dictionary(PREFIX3(streamp) strm, unsigned char *dictionary, uInt* dict_length);
 
 #define INFLATE_RESET_KEEP_HOOK(strm) \
     dfltcc_reset((strm), sizeof(struct inflate_state))
@@ -36,7 +34,7 @@ int Z_INTERNAL dfltcc_inflate_get_dictionary(PREFIX3(streamp) strm, unsigned cha
 
 #define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm)))
 
-#define INFLATE_NEED_WINDOW_OUTPUT_FLUSH(strm) (!dfltcc_can_inflate((strm)))
+#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm)))
 
 #define INFLATE_MARK_HOOK(strm) \
     do { \
@@ -48,16 +46,4 @@ int Z_INTERNAL dfltcc_inflate_get_dictionary(PREFIX3(streamp) strm, unsigned cha
         if (dfltcc_was_inflate_used((strm))) return Z_STREAM_ERROR; \
     } while (0)
 
-#define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \
-    do { \
-        if (dfltcc_can_inflate((strm))) \
-            return dfltcc_inflate_set_dictionary((strm), (dict), (dict_len)); \
-    } while (0)
-
-#define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \
-    do { \
-        if (dfltcc_can_inflate((strm))) \
-            return dfltcc_inflate_get_dictionary((strm), (dict), (dict_len)); \
-    } while (0)
-
 #endif
index 5e2af29c6cb9e97273908daa2573e4ff8d080b87..419939b1474319dea856dc8be2cdba037dcf9fcb 100644 (file)
--- a/inflate.c
+++ b/inflate.c
@@ -911,13 +911,11 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
             break;
 
         case CHECK:
-            if (INFLATE_NEED_WINDOW_OUTPUT_FLUSH(strm)) {
-                RESTORE();
-                window_output_flush(strm);
-                LOAD();
-                if (strm->avail_out == 0 && state->wnext)
-                    goto inf_leave;
-            }
+            RESTORE();
+            window_output_flush(strm);
+            LOAD();
+            if (strm->avail_out == 0 && state->wnext)
+                goto inf_leave;
             if (state->wrap) {
                 NEEDBITS(32);
                 out -= left;
@@ -984,7 +982,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
   inf_leave:
     RESTORE();
 
-    if (INFLATE_NEED_WINDOW_OUTPUT_FLUSH(strm) && strm->avail_out && state->wnext)
+    if (strm->avail_out && state->wnext)
         window_output_flush(strm);
 
     in -= strm->avail_in;
@@ -1019,12 +1017,13 @@ int32_t Z_EXPORT PREFIX(inflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *di
     /* check state */
     if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
-    INFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength);  /* hook for IBM Z DFLTCC */
     state = (struct inflate_state *)strm->state;
 
     /* copy dictionary */
-    if (state->whave && dictionary != NULL)
-        memcpy(dictionary, state->window + state->wsize - state->whave, state->whave);
+    if (state->whave && dictionary != NULL) {
+        memcpy(dictionary, state->window + state->wnext, state->whave - state->wnext);
+        memcpy(dictionary + state->whave - state->wnext, state->window, state->wnext);
+    }
     if (dictLength != NULL)
         *dictLength = state->whave;
     return Z_OK;
@@ -1033,7 +1032,7 @@ int32_t Z_EXPORT PREFIX(inflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *di
 int32_t Z_EXPORT PREFIX(inflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) {
     struct inflate_state *state;
     unsigned long dictid, dict_copy, hist_copy;
-    const unsigned char *dict_from;
+    const unsigned char *dict_from, *hist_from;
     unsigned char *dict_to, *hist_to;
     int ret;
 
@@ -1056,8 +1055,6 @@ int32_t Z_EXPORT PREFIX(inflateSetDictionary)(PREFIX3(stream) *strm, const uint8
 
     Tracec(state->wnext != 0, (stderr, "Setting dictionary with unflushed output"));
 
-    INFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength);  /* hook for IBM Z DFLTCC */
-
     /* copy dictionary to window and amend if necessary */
     dict_from = dictionary;
     dict_copy = dictLength;
@@ -1067,13 +1064,14 @@ int32_t Z_EXPORT PREFIX(inflateSetDictionary)(PREFIX3(stream) *strm, const uint8
     }
     dict_to = state->window + state->wsize - dict_copy;
 
+    hist_from = state->window + state->wsize - state->whave;
     hist_copy = state->wsize - dict_copy;
     if (hist_copy > state->whave)
         hist_copy = state->whave;
     hist_to = dict_to - hist_copy;
 
     if (hist_copy)
-        memcpy(hist_to, state->window + state->wsize - hist_copy, hist_copy);
+        memcpy(hist_to, hist_from, hist_copy);
     if (dict_copy)
         memcpy(dict_to, dict_from, dict_copy);
 
index 86e3702b864fa1962035e78bb2d3a8461aa8c592..d2aab559f3b776da6142af94af4f43edb080e6cb 100644 (file)
 #  define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0)
 /* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific inflation code already does that. */
 #  define INFLATE_NEED_CHECKSUM(strm) 1
-/* Returns whether zlib-ng should flush the window to the output buffer.
-   Set to 0 if arch-specific inflation code already does that. */
-#  define INFLATE_NEED_WINDOW_OUTPUT_FLUSH(strm) 1
+/* Returns whether zlib-ng should update a window. Set to 0 if arch-specific inflation code already does that. */
+#  define INFLATE_NEED_UPDATEWINDOW(strm) 1
 /* Invoked at the beginning of inflateMark(). Useful for updating arch-specific pointers and offsets. */
 #  define INFLATE_MARK_HOOK(strm) do {} while (0)
 /* Invoked at the beginning of inflateSyncPoint(). Useful for performing arch-specific state checks. */
 #  define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0)
-/* Invoked at the beginning of inflateSetDictionary(). Useful for checking arch-specific window data. */
-#  define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
-/* Invoked at the beginning of inflateGetDictionary(). Useful for adjusting arch-specific window data. */
-#  define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
 #endif