aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2024-02-12 17:09:10 +0200
committerLasse Collin <lasse.collin@tukaani.org>2024-02-14 18:31:16 +0200
commit5e04706b91ca90d6befd4da24a588a55e631d4a9 (patch)
tree4e23dedcf5b2f3b184bc0e564d29446e6b1b1f6f
parentliblzma: Optimize literal_subcoder() macro slightly. (diff)
downloadxz-5e04706b91ca90d6befd4da24a588a55e631d4a9.tar.xz
liblzma: LZMA decoder: Optimize loop comparison.
But now it needs one more local variable.
-rw-r--r--src/liblzma/lzma/lzma_decoder.c5
-rw-r--r--src/liblzma/rangecoder/range_decoder.h10
2 files changed, 11 insertions, 4 deletions
diff --git a/src/liblzma/lzma/lzma_decoder.c b/src/liblzma/lzma/lzma_decoder.c
index 66d2818d..f7323061 100644
--- a/src/liblzma/lzma/lzma_decoder.c
+++ b/src/liblzma/lzma/lzma_decoder.c
@@ -261,7 +261,7 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr,
const size_t dict_start = dict.pos;
// Range decoder
- rc_to_local(coder->rc, *in_pos);
+ rc_to_local(coder->rc, *in_pos, LZMA_IN_REQUIRED);
// State
uint32_t state = coder->state;
@@ -340,8 +340,7 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr,
// If there is not enough room for another LZMA symbol
// go to Resumable mode.
- if (unlikely(rc_in_end - rc_in_ptr < LZMA_IN_REQUIRED
- || dict.pos == dict.limit))
+ if (unlikely(!rc_is_fast_allowed() || dict.pos == dict.limit))
goto slow;
// Decode the first bit from the next LZMA symbol.
diff --git a/src/liblzma/rangecoder/range_decoder.h b/src/liblzma/rangecoder/range_decoder.h
index 40de80c0..8cc78e6a 100644
--- a/src/liblzma/rangecoder/range_decoder.h
+++ b/src/liblzma/rangecoder/range_decoder.h
@@ -61,13 +61,21 @@ rc_read_init(lzma_range_decoder *rc, const uint8_t *restrict in,
/// Makes local copies of range decoder and *in_pos variables. Doing this
/// improves speed significantly. The range decoder macros expect also
/// variables 'in' and 'in_size' to be defined.
-#define rc_to_local(range_decoder, in_pos) \
+#define rc_to_local(range_decoder, in_pos, fast_mode_in_required) \
lzma_range_decoder rc = range_decoder; \
const uint8_t *rc_in_ptr = in + (in_pos); \
const uint8_t *rc_in_end = in + in_size; \
+ const uint8_t *rc_in_fast_end \
+ = (rc_in_end - rc_in_ptr) <= (fast_mode_in_required) \
+ ? rc_in_ptr \
+ : rc_in_end - (fast_mode_in_required); \
uint32_t rc_bound
+/// Evaluates to true if there is enough input remaining to use fast mode.
+#define rc_is_fast_allowed() (rc_in_ptr < rc_in_fast_end)
+
+
/// Stores the local copes back to the range decoder structure.
#define rc_from_local(range_decoder, in_pos) \
do { \