mirror of
https://github.com/esphome/esphome.git
synced 2026-10-07 03:16:37 +00:00
Merge branch 'kamilcuk/use-placement-new' into integration
This commit is contained in:
@@ -11,11 +11,9 @@
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <concepts>
|
||||
#include <strings.h>
|
||||
@@ -2232,27 +2230,6 @@ template<std::totally_ordered T, comparable_with<T> U> T clamp_at_most(T value,
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provides properly aligned, uninitialized static storage for a given type T.
|
||||
*
|
||||
* This struct is designed to replace dynamic heap allocations (`new T(...)`) for
|
||||
* global or static singletons within ESPHome, preventing memory fragmentation.
|
||||
* The underlying object must be explicitly constructed using placement new
|
||||
* before access. No destructor is called — this is intentional since ESPHome
|
||||
* singletons live for the entire device lifetime.
|
||||
*/
|
||||
template<class T> struct PlacementStorage {
|
||||
/// @brief Raw byte storage, strictly aligned for type T.
|
||||
alignas(T) unsigned char data[sizeof(T)];
|
||||
|
||||
/// @brief Retrieves a pointer to the storage as the target type.
|
||||
/// The caller must ensure the object has been constructed via placement new before dereferencing.
|
||||
T *get() { return reinterpret_cast<T *>(data); }
|
||||
|
||||
/// @brief Retrieves a const pointer to the storage as the target type.
|
||||
const T *get() const { return reinterpret_cast<const T *>(data); }
|
||||
};
|
||||
|
||||
/// @name Internal functions
|
||||
///@{
|
||||
|
||||
|
||||
@@ -584,18 +584,20 @@ def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
|
||||
# For 'new' allocations, use placement new into static storage
|
||||
# to avoid heap fragmentation on embedded devices.
|
||||
the_type = id_.type
|
||||
storage_type = MockObj(f"esphome::PlacementStorage<{the_type}>")
|
||||
storage_id = ID(f"{id_.id}_storage_", type=storage_type)
|
||||
storage_name = f"{id_.id}_storage_"
|
||||
|
||||
# Declare aligned byte array for the object storage
|
||||
CORE.add_global(
|
||||
VariableDeclarationExpression(storage_type, "", storage_id, static=True)
|
||||
RawStatement(
|
||||
f"alignas({the_type}) static unsigned char {storage_name}[sizeof({the_type})];"
|
||||
)
|
||||
)
|
||||
CORE.add_global(
|
||||
AssignmentExpression(
|
||||
f"static {the_type}",
|
||||
"*const ",
|
||||
id_,
|
||||
MockObj(f"{storage_id.id}.get()"),
|
||||
MockObj(f"reinterpret_cast<{the_type} *>({storage_name})"),
|
||||
)
|
||||
)
|
||||
# Extract args from the CallExpression and rebuild as placement new.
|
||||
|
||||
Reference in New Issue
Block a user