diff options
author | Dave Watson <davejwatson@fb.com> | 2019-01-25 22:40:27 (GMT) |
---|---|---|
committer | Dave Watson <davejwatson@fb.com> | 2019-02-08 21:57:23 (GMT) |
commit | 59332a3026eaff40e4c6d3c627bdb51bfd26fea1 (patch) | |
tree | cde6ebde62f52e2738679e142ee6e456afa345d2 /lib | |
parent | 5dfa7d422ba6c184a7c7694f56bcd36e38e5ed1a (diff) | |
download | lz4-59332a3026eaff40e4c6d3c627bdb51bfd26fea1.zip lz4-59332a3026eaff40e4c6d3c627bdb51bfd26fea1.tar.gz lz4-59332a3026eaff40e4c6d3c627bdb51bfd26fea1.tar.bz2 |
decompress_generic: Optimize literal copies
Use LZ4_wildCopy16 for variable-length literals. For literal counts that
fit in the flag byte, copy directly. We can also omit oend checks for
roughly the same reason as the previous shortcut: We check once that both
match length and literal length fit in FASTLOOP_SAFE_DISTANCE, including
wildcopy distance.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/lz4.c | 33 |
1 files changed, 21 insertions, 12 deletions
@@ -1545,22 +1545,31 @@ LZ4_decompress_generic( /* decode literal length */ if (length == RUN_MASK) { - variable_length_error error = ok; - length += read_variable_length(&ip, iend-RUN_MASK, endOnInput, endOnInput, &error); - if (error == initial_error) goto _output_error; + variable_length_error error = ok; + length += read_variable_length(&ip, iend-RUN_MASK, endOnInput, endOnInput, &error); + if (error == initial_error) goto _output_error; if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error; /* overflow detection */ if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error; /* overflow detection */ - } - /* copy literals */ - cpy = op+length; - LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); - if ( ((endOnInput) && ((cpy>oend-FASTLOOP_SAFE_DISTANCE) || (ip+length>iend-(2+1+LASTLITERALS))) ) - || ((!endOnInput) && (cpy>oend-FASTLOOP_SAFE_DISTANCE)) ) - { - goto safe_literal_copy; + /* copy literals */ + cpy = op+length; + LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); + if ( ((endOnInput) && ((cpy>oend-FASTLOOP_SAFE_DISTANCE) || (ip+length>iend-(2+1+LASTLITERALS))) ) + || ((!endOnInput) && (cpy>oend-FASTLOOP_SAFE_DISTANCE)) ) + { + goto safe_literal_copy; + } + LZ4_wildCopy16(op, ip, cpy); + ip += length; op = cpy; } else { - LZ4_wildCopy(op, ip, cpy); /* may overwrite up to WILDCOPYLENGTH beyond cpy */ + cpy = op+length; + /* We don't need to check oend, since we check it once for each loop below */ + if ( ((endOnInput) && (ip+16>iend-(2+1+LASTLITERALS)))) + { + goto safe_literal_copy; + } + /* Literals can only be 14, but hope compilers optimize if we copy by a register size */ + memcpy(op, ip, 16); ip += length; op = cpy; } |