From 7dff631dcb133e69a26d841a1f0645cac812202a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 12 Feb 2026 18:20:39 -0600 Subject: [PATCH] [core] Flatten single-callsite vector realloc functions (#13970) --- esphome/components/api/api_connection.cpp | 6 ++++-- esphome/components/api/api_connection.h | 2 ++ esphome/components/api/api_server.cpp | 2 +- esphome/components/wifi/wifi_component.cpp | 13 +++++++++++++ esphome/components/wifi/wifi_component.h | 13 +------------ 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 4bc3c9b307..4d564af9e2 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1864,6 +1864,8 @@ void APIConnection::on_fatal_error() { this->flags_.remove = true; } +void __attribute__((flatten)) APIConnection::DeferredBatch::push_item(const BatchItem &item) { items.push_back(item); } + void APIConnection::DeferredBatch::add_item(EntityBase *entity, uint8_t message_type, uint8_t estimated_size, uint8_t aux_data_index) { // Check if we already have a message of this type for this entity @@ -1880,7 +1882,7 @@ void APIConnection::DeferredBatch::add_item(EntityBase *entity, uint8_t message_ } } // No existing item found (or event), add new one - items.push_back({entity, message_type, estimated_size, aux_data_index}); + this->push_item({entity, message_type, estimated_size, aux_data_index}); } void APIConnection::DeferredBatch::add_item_front(EntityBase *entity, uint8_t message_type, uint8_t estimated_size) { @@ -1888,7 +1890,7 @@ void APIConnection::DeferredBatch::add_item_front(EntityBase *entity, uint8_t me // This avoids expensive vector::insert which shifts all elements // Note: We only ever have one high-priority message at a time (ping OR disconnect) // If we're disconnecting, pings are blocked, so this simple swap is sufficient - items.push_back({entity, message_type, estimated_size, AUX_DATA_UNUSED}); + this->push_item({entity, message_type, estimated_size, AUX_DATA_UNUSED}); if (items.size() > 1) { // Swap the new high-priority item to the front std::swap(items.front(), items.back()); diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index d3d09a01c8..e34bed8ada 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -541,6 +541,8 @@ class APIConnection final : public APIServerConnectionBase { uint8_t aux_data_index = AUX_DATA_UNUSED); // Add item to the front of the batch (for high priority messages like ping) void add_item_front(EntityBase *entity, uint8_t message_type, uint8_t estimated_size); + // Single push_back site to avoid duplicate _M_realloc_insert instantiation + void push_item(const BatchItem &item); // Clear all items void clear() { diff --git a/esphome/components/api/api_server.cpp b/esphome/components/api/api_server.cpp index 5503cf4db8..211bda66de 100644 --- a/esphome/components/api/api_server.cpp +++ b/esphome/components/api/api_server.cpp @@ -195,7 +195,7 @@ void APIServer::remove_client_(size_t client_index) { #endif } -void APIServer::accept_new_connections_() { +void __attribute__((flatten)) APIServer::accept_new_connections_() { while (true) { struct sockaddr_storage source_addr; socklen_t addr_len = sizeof(source_addr); diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 61d05d7635..a2efac8d26 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -487,6 +487,19 @@ bool WiFiComponent::matches_configured_network_(const char *ssid, const uint8_t return false; } +void __attribute__((flatten)) WiFiComponent::set_sta_priority(bssid_t bssid, int8_t priority) { + for (auto &it : this->sta_priorities_) { + if (it.bssid == bssid) { + it.priority = priority; + return; + } + } + this->sta_priorities_.push_back(WiFiSTAPriority{ + .bssid = bssid, + .priority = priority, + }); +} + void WiFiComponent::log_discarded_scan_result_(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel) { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE // Skip logging during roaming scans to avoid log buffer overflow diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 53ff0d9cad..4a038f602c 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -488,18 +488,7 @@ class WiFiComponent : public Component { } return 0; } - void set_sta_priority(const bssid_t bssid, int8_t priority) { - for (auto &it : this->sta_priorities_) { - if (it.bssid == bssid) { - it.priority = priority; - return; - } - } - this->sta_priorities_.push_back(WiFiSTAPriority{ - .bssid = bssid, - .priority = priority, - }); - } + void set_sta_priority(bssid_t bssid, int8_t priority); network::IPAddresses wifi_sta_ip_addresses(); // Remove before 2026.9.0