diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-10-29 19:01:58 +0200 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-10-29 19:01:58 +0200 |
commit | 1014a9adbf2f32684865b052bab803581d416875 (patch) | |
tree | 333b518e23d4404ba529c4fe70fce27a1125492b | |
parent | bf3bec51fced9dbc800954885191e5671cb485ef (diff) | |
download | busybox-w32-1014a9adbf2f32684865b052bab803581d416875.tar.gz busybox-w32-1014a9adbf2f32684865b052bab803581d416875.tar.bz2 busybox-w32-1014a9adbf2f32684865b052bab803581d416875.zip |
decompress_bunzip2: relieve register pressure in hot function read_bunzip
function old new delta
unpack_bz2_stream 318 329 +11
read_bunzip 268 262 -6
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r-- | archival/libunarchive/decompress_bunzip2.c | 20 | ||||
-rw-r--r-- | include/unarchive.h | 2 |
2 files changed, 15 insertions, 7 deletions
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c index 8d7746a79..00ec47c75 100644 --- a/archival/libunarchive/decompress_bunzip2.c +++ b/archival/libunarchive/decompress_bunzip2.c | |||
@@ -488,18 +488,21 @@ static int get_next_block(bunzip_data *bd) | |||
488 | data are written to outbuf. Return value is number of bytes written or | 488 | data are written to outbuf. Return value is number of bytes written or |
489 | error (all errors are negative numbers). If out_fd!=-1, outbuf and len | 489 | error (all errors are negative numbers). If out_fd!=-1, outbuf and len |
490 | are ignored, data is written to out_fd and return is RETVAL_OK or error. | 490 | are ignored, data is written to out_fd and return is RETVAL_OK or error. |
491 | |||
492 | NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes | ||
493 | in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0. | ||
494 | (Why? This allows to get rid of one local variable) | ||
491 | */ | 495 | */ |
492 | int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | 496 | int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) |
493 | { | 497 | { |
494 | const uint32_t *dbuf; | 498 | const uint32_t *dbuf; |
495 | int pos, current, previous, out_count; | 499 | int pos, current, previous; |
496 | uint32_t CRC; | 500 | uint32_t CRC; |
497 | 501 | ||
498 | /* If we already have error/end indicator, return it */ | 502 | /* If we already have error/end indicator, return it */ |
499 | if (bd->writeCount < 0) | 503 | if (bd->writeCount < 0) |
500 | return bd->writeCount; | 504 | return bd->writeCount; |
501 | 505 | ||
502 | out_count = 0; | ||
503 | dbuf = bd->dbuf; | 506 | dbuf = bd->dbuf; |
504 | 507 | ||
505 | /* Register-cached state (hopefully): */ | 508 | /* Register-cached state (hopefully): */ |
@@ -520,7 +523,7 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
520 | for (;;) { | 523 | for (;;) { |
521 | 524 | ||
522 | /* If the output buffer is full, save cached state and return */ | 525 | /* If the output buffer is full, save cached state and return */ |
523 | if (out_count >= len) { | 526 | if (--len < 0) { |
524 | /* Unlikely branch. | 527 | /* Unlikely branch. |
525 | * Use of "goto" instead of keeping code here | 528 | * Use of "goto" instead of keeping code here |
526 | * helps compiler to realize this. */ | 529 | * helps compiler to realize this. */ |
@@ -528,7 +531,7 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
528 | } | 531 | } |
529 | 532 | ||
530 | /* Write next byte into output buffer, updating CRC */ | 533 | /* Write next byte into output buffer, updating CRC */ |
531 | outbuf[out_count++] = current; | 534 | *outbuf++ = current; |
532 | CRC = (CRC << 8) ^ bd->crc32Table[(CRC >> 24) ^ current]; | 535 | CRC = (CRC << 8) ^ bd->crc32Table[(CRC >> 24) ^ current]; |
533 | 536 | ||
534 | /* Loop now if we're outputting multiple copies of this byte */ | 537 | /* Loop now if we're outputting multiple copies of this byte */ |
@@ -587,7 +590,7 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
587 | int r = get_next_block(bd); | 590 | int r = get_next_block(bd); |
588 | if (r) { /* error/end */ | 591 | if (r) { /* error/end */ |
589 | bd->writeCount = r; | 592 | bd->writeCount = r; |
590 | return (r != RETVAL_LAST_BLOCK) ? r : out_count; | 593 | return (r != RETVAL_LAST_BLOCK) ? r : len; |
591 | } | 594 | } |
592 | } | 595 | } |
593 | 596 | ||
@@ -604,7 +607,7 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
604 | 607 | ||
605 | bd->writeCopies++; | 608 | bd->writeCopies++; |
606 | 609 | ||
607 | return out_count; | 610 | return 0; |
608 | } | 611 | } |
609 | 612 | ||
610 | /* Allocate the structure, read file header. If in_fd==-1, inbuf must contain | 613 | /* Allocate the structure, read file header. If in_fd==-1, inbuf must contain |
@@ -698,7 +701,10 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |||
698 | if (i == 0) { | 701 | if (i == 0) { |
699 | while (1) { /* "Produce some output bytes" loop */ | 702 | while (1) { /* "Produce some output bytes" loop */ |
700 | i = read_bunzip(bd, outbuf, IOBUF_SIZE); | 703 | i = read_bunzip(bd, outbuf, IOBUF_SIZE); |
701 | if (i <= 0) | 704 | if (i < 0) /* error? */ |
705 | break; | ||
706 | i = IOBUF_SIZE - i; /* number of bytes produced */ | ||
707 | if (i == 0) /* EOF? */ | ||
702 | break; | 708 | break; |
703 | if (i != full_write(dst_fd, outbuf, i)) { | 709 | if (i != full_write(dst_fd, outbuf, i)) { |
704 | bb_error_msg("short write"); | 710 | bb_error_msg("short write"); |
diff --git a/include/unarchive.h b/include/unarchive.h index 11d8c77a0..ba6d323e0 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
@@ -194,6 +194,8 @@ extern const llist_t *find_list_entry2(const llist_t *list, const char *filename | |||
194 | /* A bit of bunzip2 internals are exposed for compressed help support: */ | 194 | /* A bit of bunzip2 internals are exposed for compressed help support: */ |
195 | typedef struct bunzip_data bunzip_data; | 195 | typedef struct bunzip_data bunzip_data; |
196 | int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; | 196 | int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; |
197 | /* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes | ||
198 | * in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */ | ||
197 | int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; | 199 | int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; |
198 | void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; | 200 | void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; |
199 | 201 | ||