diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-01-31 16:11:44 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-01-31 16:11:56 +0100 |
commit | 05251986c7c00b07a5a7ff0f70258e53a3f3de9e (patch) | |
tree | ea84e7fc00018c7f664434ea36dca7107c419029 | |
parent | 8fd35a1fa629daed5e4e580e72993df7654f0a5e (diff) | |
download | busybox-w32-05251986c7c00b07a5a7ff0f70258e53a3f3de9e.tar.gz busybox-w32-05251986c7c00b07a5a7ff0f70258e53a3f3de9e.tar.bz2 busybox-w32-05251986c7c00b07a5a7ff0f70258e53a3f3de9e.zip |
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 <vda.linux@googlemail.com>
-rw-r--r-- | archival/gzip.c | 108 |
1 files 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 { | |||
300 | 300 | ||
301 | 301 | ||
302 | struct globals { | 302 | struct globals { |
303 | /* =========================================================================== */ | ||
304 | /* global buffers, allocated once */ | ||
305 | |||
306 | #define DECLARE(type, array, size) \ | ||
307 | type * array | ||
308 | #define ALLOC(type, array, size) \ | ||
309 | array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)) | ||
310 | #define FREE(array) \ | ||
311 | do { free(array); array = NULL; } while (0) | ||
312 | |||
313 | /* buffer for literals or lengths */ | ||
314 | /* DECLARE(uch, l_buf, LIT_BUFSIZE); */ | ||
315 | DECLARE(uch, l_buf, INBUFSIZ); | ||
316 | |||
317 | DECLARE(ush, d_buf, DIST_BUFSIZE); | ||
318 | DECLARE(uch, outbuf, OUTBUFSIZ); | ||
319 | |||
320 | /* Sliding window. Input bytes are read into the second half of the window, | ||
321 | * and move to the first half later to keep a dictionary of at least WSIZE | ||
322 | * bytes. With this organization, matches are limited to a distance of | ||
323 | * WSIZE-MAX_MATCH bytes, but this ensures that IO is always | ||
324 | * performed with a length multiple of the block size. Also, it limits | ||
325 | * the window size to 64K, which is quite useful on MSDOS. | ||
326 | * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would | ||
327 | * be less efficient). | ||
328 | */ | ||
329 | DECLARE(uch, window, 2L * WSIZE); | ||
330 | |||
331 | /* Link to older string with same hash index. To limit the size of this | ||
332 | * array to 64K, this link is maintained only for the last 32K strings. | ||
333 | * An index in this array is thus a window index modulo 32K. | ||
334 | */ | ||
335 | /* DECLARE(Pos, prev, WSIZE); */ | ||
336 | DECLARE(ush, prev, 1L << BITS); | ||
337 | |||
338 | /* Heads of the hash chains or 0. */ | ||
339 | /* DECLARE(Pos, head, 1<<HASH_BITS); */ | ||
340 | #define head (G1.prev + WSIZE) /* hash head (see deflate.c) */ | ||
341 | |||
342 | /* =========================================================================== */ | ||
343 | /* all members below are zeroed out in pack_gzip() for each next file */ | ||
344 | |||
345 | uint32_t crc; /* shift register contents */ | ||
346 | /*uint32_t *crc_32_tab;*/ | ||
303 | 347 | ||
304 | #if ENABLE_FEATURE_GZIP_LEVELS | 348 | #if ENABLE_FEATURE_GZIP_LEVELS |
305 | unsigned max_chain_length; | 349 | unsigned max_chain_length; |
@@ -368,49 +412,6 @@ struct globals { | |||
368 | #ifdef DEBUG | 412 | #ifdef DEBUG |
369 | ulg bits_sent; /* bit length of the compressed data */ | 413 | ulg bits_sent; /* bit length of the compressed data */ |
370 | #endif | 414 | #endif |
371 | |||
372 | /*uint32_t *crc_32_tab;*/ | ||
373 | uint32_t crc; /* shift register contents */ | ||
374 | |||
375 | /* =========================================================================== | ||
376 | */ | ||
377 | #define DECLARE(type, array, size) \ | ||
378 | type * array | ||
379 | #define ALLOC(type, array, size) \ | ||
380 | array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)) | ||
381 | #define FREE(array) \ | ||
382 | do { free(array); array = NULL; } while (0) | ||
383 | |||
384 | /* global buffers */ | ||
385 | |||
386 | /* buffer for literals or lengths */ | ||
387 | /* DECLARE(uch, l_buf, LIT_BUFSIZE); */ | ||
388 | DECLARE(uch, l_buf, INBUFSIZ); | ||
389 | |||
390 | DECLARE(ush, d_buf, DIST_BUFSIZE); | ||
391 | DECLARE(uch, outbuf, OUTBUFSIZ); | ||
392 | |||
393 | /* Sliding window. Input bytes are read into the second half of the window, | ||
394 | * and move to the first half later to keep a dictionary of at least WSIZE | ||
395 | * bytes. With this organization, matches are limited to a distance of | ||
396 | * WSIZE-MAX_MATCH bytes, but this ensures that IO is always | ||
397 | * performed with a length multiple of the block size. Also, it limits | ||
398 | * the window size to 64K, which is quite useful on MSDOS. | ||
399 | * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would | ||
400 | * be less efficient). | ||
401 | */ | ||
402 | DECLARE(uch, window, 2L * WSIZE); | ||
403 | |||
404 | /* Link to older string with same hash index. To limit the size of this | ||
405 | * array to 64K, this link is maintained only for the last 32K strings. | ||
406 | * An index in this array is thus a window index modulo 32K. | ||
407 | */ | ||
408 | /* DECLARE(Pos, prev, WSIZE); */ | ||
409 | DECLARE(ush, prev, 1L << BITS); | ||
410 | |||
411 | /* Heads of the hash chains or 0. */ | ||
412 | /* DECLARE(Pos, head, 1<<HASH_BITS); */ | ||
413 | #define head (G1.prev + WSIZE) /* hash head (see deflate.c) */ | ||
414 | }; | 415 | }; |
415 | 416 | ||
416 | #define G1 (*(ptr_to_globals - 1)) | 417 | #define G1 (*(ptr_to_globals - 1)) |
@@ -460,6 +461,7 @@ static void put_16bit(ush w) | |||
460 | } | 461 | } |
461 | *dst = (uch)w; | 462 | *dst = (uch)w; |
462 | w >>= 8; | 463 | w >>= 8; |
464 | G1.outcnt = ++outcnt; | ||
463 | #else | 465 | #else |
464 | *dst = (uch)w; | 466 | *dst = (uch)w; |
465 | w >>= 8; | 467 | w >>= 8; |
@@ -469,13 +471,13 @@ static void put_16bit(ush w) | |||
469 | G1.outcnt = outcnt + 2; | 471 | G1.outcnt = outcnt + 2; |
470 | return; | 472 | return; |
471 | } | 473 | } |
474 | G1.outcnt = ++outcnt; | ||
472 | #endif | 475 | #endif |
473 | 476 | ||
474 | /* Slowpath: we will need to do flush_outbuf() */ | 477 | /* Slowpath: we will need to do flush_outbuf() */ |
475 | G1.outcnt = ++outcnt; | ||
476 | if (outcnt == OUTBUFSIZ) | 478 | if (outcnt == OUTBUFSIZ) |
477 | flush_outbuf(); | 479 | flush_outbuf(); /* here */ |
478 | put_8bit(w); | 480 | put_8bit(w); /* or here */ |
479 | } | 481 | } |
480 | 482 | ||
481 | #define OPTIMIZED_PUT_32BIT (CONFIG_GZIP_FAST > 0 && BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN) | 483 | #define OPTIMIZED_PUT_32BIT (CONFIG_GZIP_FAST > 0 && BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN) |
@@ -2056,17 +2058,20 @@ static void ct_init(void) | |||
2056 | G2.static_ltree[n++].Len = 9; | 2058 | G2.static_ltree[n++].Len = 9; |
2057 | //G2.bl_count[9]++; | 2059 | //G2.bl_count[9]++; |
2058 | } | 2060 | } |
2059 | G2.bl_count[9] = 255 - 143; | 2061 | //G2.bl_count[9] = 255 - 143; |
2060 | while (n <= 279) { | 2062 | while (n <= 279) { |
2061 | G2.static_ltree[n++].Len = 7; | 2063 | G2.static_ltree[n++].Len = 7; |
2062 | //G2.bl_count[7]++; | 2064 | //G2.bl_count[7]++; |
2063 | } | 2065 | } |
2064 | G2.bl_count[7] = 279 - 255; | 2066 | //G2.bl_count[7] = 279 - 255; |
2065 | while (n <= 287) { | 2067 | while (n <= 287) { |
2066 | G2.static_ltree[n++].Len = 8; | 2068 | G2.static_ltree[n++].Len = 8; |
2067 | //G2.bl_count[8]++; | 2069 | //G2.bl_count[8]++; |
2068 | } | 2070 | } |
2069 | G2.bl_count[8] = 287 - 279 + (143 + 1); | 2071 | //G2.bl_count[8] += 287 - 279; |
2072 | G2.bl_count[7] = 279 - 255; | ||
2073 | G2.bl_count[8] = (143 + 1) + (287 - 279); | ||
2074 | G2.bl_count[9] = 255 - 143; | ||
2070 | /* Codes 286 and 287 do not exist, but we must include them in the | 2075 | /* Codes 286 and 287 do not exist, but we must include them in the |
2071 | * tree construction to get a canonical Huffman tree (longest code | 2076 | * tree construction to get a canonical Huffman tree (longest code |
2072 | * all ones) | 2077 | * all ones) |
@@ -2132,8 +2137,8 @@ static void zip(void) | |||
2132 | static | 2137 | static |
2133 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) | 2138 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) |
2134 | { | 2139 | { |
2135 | /* Reinit G1.xxx except pointers to allocated buffers */ | 2140 | /* Reinit G1.xxx except pointers to allocated buffers, and entire G2 */ |
2136 | memset(&G1, 0, offsetof(struct globals, l_buf)); | 2141 | memset(&G1.crc, 0, (sizeof(G1) - offsetof(struct globals, crc)) + sizeof(G2)); |
2137 | 2142 | ||
2138 | /* Clear input and output buffers */ | 2143 | /* Clear input and output buffers */ |
2139 | //G1.outcnt = 0; | 2144 | //G1.outcnt = 0; |
@@ -2143,7 +2148,6 @@ IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED | |||
2143 | //G1.isize = 0; | 2148 | //G1.isize = 0; |
2144 | 2149 | ||
2145 | /* Reinit G2.xxx */ | 2150 | /* Reinit G2.xxx */ |
2146 | memset(&G2, 0, sizeof(G2)); | ||
2147 | G2.l_desc.dyn_tree = G2.dyn_ltree; | 2151 | G2.l_desc.dyn_tree = G2.dyn_ltree; |
2148 | G2.l_desc.static_tree = G2.static_ltree; | 2152 | G2.l_desc.static_tree = G2.static_ltree; |
2149 | G2.l_desc.extra_bits = extra_lbits; | 2153 | G2.l_desc.extra_bits = extra_lbits; |