From 7759b0b43d4c0f831a2d3c4ed5a4eec4fcad0950 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 10 Feb 2024 20:34:22 -0600 Subject: [PATCH] Reduce stack allocation in the little-leb128 decoder This avoids the extra stack allocation for the unaligned worst-case leb128 encoding by duplicating most of the "big-leb128" decoder. The upside is less stack usage, but at a code cost, since we basically have two copies of this function now. This is a bit of a tough call, the percentage change is basically the same: code stack before: 33700 2800 after: 33808 (+0.3%) 2792 (-0.3%) On one hand, we would want to deduplicate these functions if they end up with the same encoding cost (28-bit littlefs mode?), and less code is less code, on the other hand, RAM is in general more valuable than code... This may be worth reverting in the future... --- lfs.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lfs.c b/lfs.c index 22d6c683..f2996219 100644 --- a/lfs.c +++ b/lfs.c @@ -1273,14 +1273,25 @@ static int lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t *data, // resulting leb128 encoding fits nicely in 4-bytes static inline int lfsr_data_readlleb128(lfs_t *lfs, lfsr_data_t *data, uint32_t *word_) { - // just call readleb128 here - int err = lfsr_data_readleb128(lfs, data, word_); - if (err) { - return err; + // note we make sure not to update our data offset until after leb128 + // decoding + lfsr_data_t data_ = *data; + + // for 28-bits we can assume worst-case leb128 size is 4-bytes + uint8_t buf[4]; + lfs_ssize_t d = lfsr_data_read(lfs, &data_, buf, 4); + if (d < 0) { + return d; } + d = lfs_fromleb128(word_, buf, d); + if (d < 0) { + return d; + } // little-leb128s should be limited to 28-bits LFS_ASSERT(*word_ <= 0x0fffffff); + + *data = lfsr_data_slice(*data, d, -1); return 0; }