From 05251986c7c00b07a5a7ff0f70258e53a3f3de9e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 31 Jan 2018 16:11:44 +0100 Subject: [PATCH] gzip: code shrink Use one memset to clear part of G1, and all of G2. function old new delta pack_gzip 838 828 -10 Signed-off-by: Denys Vlasenko --- archival/gzip.c | 108 +++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/archival/gzip.c b/archival/gzip.c index d52167f84..9dc31e30b 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -300,6 +300,50 @@ enum { struct globals { +/* =========================================================================== */ +/* global buffers, allocated once */ + +#define DECLARE(type, array, size) \ + type * array +#define ALLOC(type, array, size) \ + array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)) +#define FREE(array) \ + do { free(array); array = NULL; } while (0) + + /* buffer for literals or lengths */ + /* DECLARE(uch, l_buf, LIT_BUFSIZE); */ + DECLARE(uch, l_buf, INBUFSIZ); + + DECLARE(ush, d_buf, DIST_BUFSIZE); + DECLARE(uch, outbuf, OUTBUFSIZ); + +/* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least WSIZE + * bytes. With this organization, matches are limited to a distance of + * WSIZE-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would + * be less efficient). + */ + DECLARE(uch, window, 2L * WSIZE); + +/* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + /* DECLARE(Pos, prev, WSIZE); */ + DECLARE(ush, prev, 1L << BITS); + +/* Heads of the hash chains or 0. */ + /* DECLARE(Pos, head, 1<>= 8; + G1.outcnt = ++outcnt; #else *dst = (uch)w; w >>= 8; @@ -469,13 +471,13 @@ static void put_16bit(ush w) G1.outcnt = outcnt + 2; return; } + G1.outcnt = ++outcnt; #endif /* Slowpath: we will need to do flush_outbuf() */ - G1.outcnt = ++outcnt; if (outcnt == OUTBUFSIZ) - flush_outbuf(); - put_8bit(w); + flush_outbuf(); /* here */ + put_8bit(w); /* or here */ } #define OPTIMIZED_PUT_32BIT (CONFIG_GZIP_FAST > 0 && BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN) @@ -2056,17 +2058,20 @@ static void ct_init(void) G2.static_ltree[n++].Len = 9; //G2.bl_count[9]++; } - G2.bl_count[9] = 255 - 143; + //G2.bl_count[9] = 255 - 143; while (n <= 279) { G2.static_ltree[n++].Len = 7; //G2.bl_count[7]++; } - G2.bl_count[7] = 279 - 255; + //G2.bl_count[7] = 279 - 255; while (n <= 287) { G2.static_ltree[n++].Len = 8; //G2.bl_count[8]++; } - G2.bl_count[8] = 287 - 279 + (143 + 1); + //G2.bl_count[8] += 287 - 279; + G2.bl_count[7] = 279 - 255; + G2.bl_count[8] = (143 + 1) + (287 - 279); + G2.bl_count[9] = 255 - 143; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) @@ -2132,8 +2137,8 @@ static void zip(void) static IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) { - /* Reinit G1.xxx except pointers to allocated buffers */ - memset(&G1, 0, offsetof(struct globals, l_buf)); + /* Reinit G1.xxx except pointers to allocated buffers, and entire G2 */ + memset(&G1.crc, 0, (sizeof(G1) - offsetof(struct globals, crc)) + sizeof(G2)); /* Clear input and output buffers */ //G1.outcnt = 0; @@ -2143,7 +2148,6 @@ IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED //G1.isize = 0; /* Reinit G2.xxx */ - memset(&G2, 0, sizeof(G2)); G2.l_desc.dyn_tree = G2.dyn_ltree; G2.l_desc.static_tree = G2.static_ltree; G2.l_desc.extra_bits = extra_lbits;