Replace ProtoVarInt temporaries with direct uint32_t encoding functions
to avoid unnecessary 64-bit widening on 32-bit architectures (ESP32 Xtensa).
- Add encode_varint_to_buffer() free function for direct buffer encoding
- Replace encode_varint_raw(ProtoVarInt) with uint32_t-native implementation
- Add encode_varint_raw_64() for the few call sites needing 64-bit (BLE)
- Remove unused ProtoVarInt::encode() and encode_to_buffer_unchecked()
- Remove dead null checks from ProtoVarInt::parse()
Net savings: -152 bytes flash on ESP32 IDF.
NVS/FDB write failures are permanent (flash worn out, partition full,
handle invalid). The NVS layer already performs internal garbage
collection during writes, so retrying the same call will always fail
again. Keeping failed entries in the vector leaked memory and forced
a reverse-iterate + per-element erase pattern that generated ~130
bytes of inlined vector move/destroy code for NVSData objects.
Replace with a forward range-for and a single clear() at the end.
Add compile-time check that DeferredEvent has no padding, so future
field additions would trigger a build error rather than silently
reintroducing the unaligned access codegen issue.
Update comments to reference pointer sizes instead of hardcoded "8 bytes".
DeferredEvent contains two pointers (void* + function pointer), which
are already naturally 4-byte aligned on all ESPHome targets. The struct
is 8 bytes with no padding regardless of packed.
The packed attribute forces the compiler to use byte-by-byte loads and
stores instead of word-aligned access, bloating deq_push_back_with_dedup_
from 163 to 317 bytes due to shift/mask/or sequences for every field
access.
The packed attribute was added in #7538 likely to guarantee the struct
stayed at 8 bytes, but this is already the case without it since both
fields are pointer-sized.
Replace SmallBufferWithHeapFallback with a fixed stack buffer sized
to the physical storage limit. No single preference can exceed the
storage it resides in, so heap allocation is never needed.
ESP8266: buffer sized to max(flash_storage, rtc_normal_region) —
128 words (512B) with restore_from_flash, 96 words (384B) without.
RP2040: buffer sized to flash storage (512B).
Eliminates new[]/delete[] codegen from save()/load() virtual methods.