Skip to content

Commit

Permalink
speed improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Laurence Bank authored and Laurence Bank committed Mar 2, 2024
1 parent f76f8f4 commit b7dcf60
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
45 changes: 34 additions & 11 deletions src/inffast.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
#define ALLOWS_UNALIGNED
#endif

#if INTPTR_MAX == INT64_MAX
#define REGISTER_WIDTH 64
typedef uint64_t BIGUINT;
typedef uint32_t SMALLUINT;
#else
#define REGISTER_WIDTH 32
typedef uint32_t BIGUINT;
typedef uint16_t SMALLUINT;
#endif // native register size

#ifdef ASMINF
# pragma message("Assembler code may have bugs -- use at your own risk")
#else
Expand Down Expand Up @@ -68,7 +78,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
BIGUINT hold, tmpbits; /* local strm->hold */
// unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *dcode; /* local strm->distcode */
Expand Down Expand Up @@ -105,11 +116,12 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
do {
if (bits < 15) {
if (bits < (REGISTER_WIDTH/2)) { // helps on 32 and 64-bit CPUs
#ifdef ALLOWS_UNALIGNED
hold |= (*(uint16_t *)in << bits);
in += 2;
bits += 16;
tmpbits = *(SMALLUINT *)in;
hold |= (BIGUINT)(tmpbits << bits);
in += sizeof(SMALLUINT);
bits += (REGISTER_WIDTH / 2);
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
Expand All @@ -133,20 +145,29 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
len = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (op) {
#if REGISTER_WIDTH == 32
if (bits < op) {
hold += (unsigned long)(*in++) << bits;
hold += (uint32_t)(*in++) << bits;
bits += 8;
}
#endif
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
if (bits < (REGISTER_WIDTH/2)) { // helps on 32 and 64-bit CPUs
#ifdef UNALIGNED_OK
tmpbits = *(SMALLUINT *)in;
hold |= (BIGUINT)(tmpbits << bits);
in += sizeof(SMALLUINT);
bits += (REGISTER_WIDTH / 2);
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
#endif
}
here = dcode[hold & dmask];
dodist:
Expand All @@ -157,6 +178,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
if (op & 16) { /* distance base */
dist = (unsigned)(here.val);
op &= 15; /* number of extra bits */
#if REGISTER_WIDTH == 32
if (bits < op) {
#ifdef ALLOWS_UNALIGNED
hold |= (*(uint16_t *)in << bits);
Expand All @@ -171,6 +193,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
#endif // ALLOWS_UNALIGNED
}
#endif // 32-bit CPU
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
Expand Down Expand Up @@ -348,10 +371,10 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
} while (in < last && out < end);

/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
len = bits >> 3;
in -= len;
bits -= len << 3;
hold &= (1U << bits) - 1;
// len = bits >> 3;
// in -= len;
// bits -= len << 3;
// hold &= (1 << bits) - 1;

/* update state and return */
strm->next_in = in;
Expand Down
3 changes: 2 additions & 1 deletion src/inflate.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ int value;
state->bits = 0;
return Z_OK;
}
if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
if (bits > 16 || state->bits + (uInt)bits > 32)
return Z_STREAM_ERROR;
value &= (1L << bits) - 1;
state->hold += (unsigned)value << state->bits;
state->bits += (uInt)bits;
Expand Down
3 changes: 2 additions & 1 deletion src/inflate.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ struct inflate_state {
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
uint64_t hold; /* input bit accumulator */
// unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
Expand Down

0 comments on commit b7dcf60

Please sign in to comment.