diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-01-30 23:47:45 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-01-30 23:47:45 +0100 |
commit | 6ba6a6f28e456c0148abece678eab1c1194632f2 (patch) | |
tree | 8451e69dfeea79cdc9bbc481ecf54ca3fff198c1 | |
parent | e4c4e6ddc365d8e9b5409e2f929116624c932c1d (diff) | |
download | busybox-6ba6a6f28e456c0148abece678eab1c1194632f2.tar.gz |
gzip: use wider (32-bit, not 16) bi_buf
function old new delta
bi_windup 76 74 -2
send_bits 70 62 -8
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/gzip.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/archival/gzip.c b/archival/gzip.c index efc5a0eea..4a3fe976a 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -355,7 +355,7 @@ struct globals { /* Output buffer. bits are inserted starting at the bottom (least significant * bits). */ - unsigned short bi_buf; + unsigned bi_buf; /* was unsigned short */ #undef BUF_SIZE #define BUF_SIZE (int)(8 * sizeof(G1.bi_buf)) @@ -530,17 +530,25 @@ static void send_bits(int value, int length) Assert(length > 0 && length <= 15, "invalid length"); G1.bits_sent += length; #endif + BUILD_BUG_ON(BUF_SIZE != 32 && BUF_SIZE != 16); new_buf = G1.bi_buf | (value << G1.bi_valid); + /* NB: the above may sometimes do "<< 32" shift (undefined) + * if check below is changed to "length > remain" instead of >= */ remain = BUF_SIZE - G1.bi_valid; - /* If not enough room in bi_buf */ - if (length > remain) { + + /* If bi_buf is full */ + if (length >= remain) { /* ...use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, - * leaving (width - (16-bi_valid)) unused bits in value. + * (BUF_SIZE - bi_valid) bits from value, + * leaving (width - (BUF_SIZE-bi_valid)) unused bits in value. */ - put_16bit(new_buf); - new_buf = (ush) value >> remain; + if (BUF_SIZE == 32) { + put_32bit(new_buf); /* maybe unroll to 2*put_16bit()? */ + } else { /* 16 */ + put_16bit(new_buf); + } + new_buf = (unsigned) value >> remain; length -= BUF_SIZE; } G1.bi_buf = new_buf; @@ -571,10 +579,13 @@ static unsigned bi_reverse(unsigned code, int len) */ static void bi_windup(void) { - if (G1.bi_valid > 8) { - put_16bit(G1.bi_buf); - } else if (G1.bi_valid > 0) { - put_8bit(G1.bi_buf); + unsigned bits = G1.bi_buf; + int cnt = G1.bi_valid; + + while (cnt > 0) { + put_8bit(bits); + bits >>= 8; + cnt -= 8; } G1.bi_buf = 0; G1.bi_valid = 0; |