From 062f223876c023cfed04b48140c6841019c0d0ca Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 14 Feb 2026 15:43:50 -0700 Subject: [PATCH] [json, core] Remove stored RAMAllocator, make constructors constexpr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RAMAllocator with default flags is stateless — it's just a dispatch wrapper over heap_caps_malloc/realloc/free. Remove the stored member from SpiRamAllocator, using stack-local instances at each call site. Also make RAMAllocator constructors constexpr so the compiler can fully evaluate flag logic at compile time. Note: SpiRamAllocator was initialized with RAMAllocator::NONE (0), which is equivalent to default construction since the constructor preserves the default ALLOC_INTERNAL | ALLOC_EXTERNAL flags when no valid allocation flags are provided. Co-Authored-By: J. Nick Koston --- esphome/components/json/json_util.h | 11 ++++++----- esphome/core/helpers.h | 11 ++++------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/esphome/components/json/json_util.h b/esphome/components/json/json_util.h index ca074926bd..c472b9a9ec 100644 --- a/esphome/components/json/json_util.h +++ b/esphome/components/json/json_util.h @@ -18,7 +18,10 @@ namespace json { // Build an allocator for the JSON Library using the RAMAllocator class // This is only compiled when PSRAM is enabled struct SpiRamAllocator : ArduinoJson::Allocator { - void *allocate(size_t size) override { return allocator_.allocate(size); } + void *allocate(size_t size) override { + RAMAllocator allocator; + return allocator.allocate(size); + } void deallocate(void *ptr) override { // ArduinoJson's Allocator interface doesn't provide the size parameter in deallocate. @@ -31,11 +34,9 @@ struct SpiRamAllocator : ArduinoJson::Allocator { } void *reallocate(void *ptr, size_t new_size) override { - return allocator_.reallocate(static_cast(ptr), new_size); + RAMAllocator allocator; + return allocator.reallocate(static_cast(ptr), new_size); } - - protected: - RAMAllocator allocator_{RAMAllocator::NONE}; }; #endif diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 34c7452484..298b93fbc4 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -1673,13 +1673,10 @@ template class RAMAllocator { ALLOW_FAILURE = 1 << 2, // Does nothing. Kept for compatibility. }; - RAMAllocator() = default; - RAMAllocator(uint8_t flags) { - // default is both external and internal - flags &= ALLOC_INTERNAL | ALLOC_EXTERNAL; - if (flags != 0) - this->flags_ = flags; - } + constexpr RAMAllocator() = default; + constexpr RAMAllocator(uint8_t flags) + : flags_((flags & (ALLOC_INTERNAL | ALLOC_EXTERNAL)) != 0 ? (flags & (ALLOC_INTERNAL | ALLOC_EXTERNAL)) + : (ALLOC_INTERNAL | ALLOC_EXTERNAL)) {} template constexpr RAMAllocator(const RAMAllocator &other) : flags_{other.flags_} {} T *allocate(size_t n) { return this->allocate(n, sizeof(T)); }