aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2010-10-29 19:01:58 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2010-10-29 19:01:58 +0200
commit1014a9adbf2f32684865b052bab803581d416875 (patch)
tree333b518e23d4404ba529c4fe70fce27a1125492b
parentbf3bec51fced9dbc800954885191e5671cb485ef (diff)
downloadbusybox-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.c20
-rw-r--r--include/unarchive.h2
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*/
492int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) 496int 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: */
195typedef struct bunzip_data bunzip_data; 195typedef struct bunzip_data bunzip_data;
196int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; 196int 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: */
197int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; 199int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC;
198void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; 200void dealloc_bunzip(bunzip_data *bd) FAST_FUNC;
199 201