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...
This commit is contained in:
Christopher Haster
2024-02-10 20:34:22 -06:00
parent 42ec282a03
commit 7759b0b43d
+15 -4
View File
@@ -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;
}