data: Adopted more object-like lfs3_data_t operations

As much as I don't want to admit it, our 3-word lfs3_data_t struct is
just too large to be treated as pass-by-value with today's compilers.

It's a real shame, because I don't think there's a great technical
reason, just that compiler's pass-by-value optimizations generally stop
after 2 words.

If we could expect 16-bit block sizes (off and size), we could fit in
2 words, but this is already challenged by today's NAND chips
(bs>=128KiB).

---

So, as a compromise, this stops treating lfs3_data_t as pass-by-value,
with the exception of the lfs3_data_from* functions that still return
lfs3_data_t directly.

So instead of:

  lfs3_data_t data = lfs3_data_fromecksum(&ecksum, buffer);
  data = lfs3_data_slice(data, 8, -1);
  return lfs3_data_size(data);

Most operations take lfs3_data_t by pointer:

  lfs3_data_t data = lfs3_data_fromecksum(&ecksum, buffer);
  lfs3_data_slice(&data, 8, -1);
  return lfs3_data_size(&data);

One of the main consequences is there are now several ways to slice data
(internally these all redirect to lfs3_data_slice), and LFS3_DATA_SLICE
will likely see more use since we need temporary allocations to pass the
data slice by address:

- lfs3_data_slice(data, a, b) - Slices the data in place
- lfs3_data_fromslice(data, a, b) - Returns a new data slice
- LFS3_DATA_SLICE(data, a, b) - Creates a new compound-literal slice

---

As a pragmatic compromise, this saves a nice chunk of both code and
stack:

                 code          stack          ctx
  before:       35316           2176          660
  after:        35188 (-0.4%)   2136 (-1.8%)  660 (+0.0%)

                 code          stack          ctx
  gbmap before: 38172           2192          772
  gbmap after:  38048 (-0.3%)   2152 (-1.8%)  772 (+0.0%)
This commit is contained in:
Christopher Haster
2025-12-01 15:51:21 -06:00
parent b63237555b
commit 321e33d5d5
4 changed files with 635 additions and 630 deletions
+10 -10
View File
@@ -213,7 +213,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// keep track of how many fragments we've seen
fragments += 1;
@@ -361,7 +361,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// if block crystallization is working we shouldn't be
// left with any inlined data fragments
@@ -627,7 +627,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// keep track of how many fragments we've seen
fragments += 1;
@@ -790,7 +790,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// if block crystallization is working we shouldn't be
// left with any inlined data fragments
@@ -2118,7 +2118,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// keep track of how many fragments we've seen
fragments += 1;
@@ -2270,7 +2270,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// keep track of how many fragments we've seen
fragments += 1;
@@ -2569,7 +2569,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// keep track of how many fragments we've seen
fragments += 1;
@@ -2736,7 +2736,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// if block crystallization is working we shouldn't be
// left with any inlined data fragments
@@ -3029,7 +3029,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// keep track of how many fragments we've seen
fragments += 1;
@@ -3200,7 +3200,7 @@ code = '''
bid,
tag,
weight,
lfs3_data_size(data));
lfs3_data_size(&data));
// if block crystallization is working we shouldn't be
// left with any inlined data fragments