From bf9e3213f2df8cef7ce45fbc06f0cb2af8ad14e9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 12 Feb 2026 16:28:57 -0600 Subject: [PATCH] [core] Flatten single-callsite vector realloc functions On ESP8266 (GCC 10.3), std::vector::push_back/emplace_back emit separate _M_realloc_insert functions even when called from only one site. Adding __attribute__((flatten)) inlines the realloc path, saving the out-of-line function overhead. Changes: - wifi: Move set_sta_priority from header to .cpp (eliminates duplicate instantiation at 2 call sites) and add flatten - web_server_base: Flatten add_handler (single push_back site) - api: Flatten accept_new_connections_ (single emplace_back site) Saves 160 bytes of flash on ESP8266. --- esphome/components/api/api_server.cpp | 2 +- .../components/web_server_base/web_server_base.cpp | 2 +- esphome/components/wifi/wifi_component.cpp | 13 +++++++++++++ esphome/components/wifi/wifi_component.h | 13 +------------ 4 files changed, 16 insertions(+), 14 deletions(-) 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/web_server_base/web_server_base.cpp b/esphome/components/web_server_base/web_server_base.cpp index 6e7097338c..4ad94dbb04 100644 --- a/esphome/components/web_server_base/web_server_base.cpp +++ b/esphome/components/web_server_base/web_server_base.cpp @@ -11,7 +11,7 @@ static const char *const TAG = "web_server_base"; WebServerBase *global_web_server_base = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) -void WebServerBase::add_handler(AsyncWebHandler *handler) { +void __attribute__((flatten)) WebServerBase::add_handler(AsyncWebHandler *handler) { // remove all handlers #ifdef USE_WEBSERVER_AUTH diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 61d05d7635..13febb2b12 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(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 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..cc89b7677f 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(const bssid_t bssid, int8_t priority); network::IPAddresses wifi_sta_ip_addresses(); // Remove before 2026.9.0