From b0b207eddbfd3a5be36e7ede8a41d7bb4947701c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 15 Sep 2025 21:34:19 -0500 Subject: [PATCH] cleanup --- esphome/components/json/json_util.cpp | 20 ++++++++++++++------ esphome/components/json/json_util.h | 7 +++---- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/esphome/components/json/json_util.cpp b/esphome/components/json/json_util.cpp index e03f95fe7c..a9cf383a18 100644 --- a/esphome/components/json/json_util.cpp +++ b/esphome/components/json/json_util.cpp @@ -71,17 +71,25 @@ bool parse_json(const std::string &data, const json_parse_t &f) { } // JsonBuilder implementation -JsonBuilder::JsonBuilder() - : doc_( +JsonBuilder::JsonBuilder() { #ifdef USE_PSRAM - (allocator_ = std::make_unique(), allocator_.get()) + // Verify our storage is large enough (and log the actual size for reference) + static_assert(sizeof(SpiRamAllocator) <= sizeof(allocator_storage_), "allocator_storage_ too small"); + // Note: sizeof(SpiRamAllocator) is typically around 24-32 bytes on ESP32 + // Use placement new to construct SpiRamAllocator in the pre-allocated storage + auto *allocator = new (allocator_storage_) SpiRamAllocator(); + doc_ = JsonDocument(allocator); #else - nullptr + doc_ = JsonDocument(); #endif - ) { } -JsonBuilder::~JsonBuilder() = default; +JsonBuilder::~JsonBuilder() { +#ifdef USE_PSRAM + // Explicitly call destructor for placement-new allocated object + reinterpret_cast(allocator_storage_)->~SpiRamAllocator(); +#endif +} std::string JsonBuilder::serialize() { if (doc_.overflowed()) { diff --git a/esphome/components/json/json_util.h b/esphome/components/json/json_util.h index 633e8182fb..de76ca53da 100644 --- a/esphome/components/json/json_util.h +++ b/esphome/components/json/json_util.h @@ -25,9 +25,6 @@ std::string build_json(const json_build_t &f); /// Parse a JSON string and run the provided json parse function if it's valid. bool parse_json(const std::string &data, const json_parse_t &f); -// Forward declaration to avoid exposing implementation details -struct SpiRamAllocator; - /// Builder class for creating JSON documents without lambdas class JsonBuilder { public: @@ -46,7 +43,9 @@ class JsonBuilder { private: #ifdef USE_PSRAM - std::unique_ptr allocator_; // One heap allocation, but keeps code clean + // Storage for SpiRamAllocator - typically around 24-32 bytes on ESP32 + // Static assert in .cpp file ensures this is large enough + std::aligned_storage<32, alignof(void *)>::type allocator_storage_; #endif JsonDocument doc_; JsonObject root_;