From 34345b86fa6ca0252c8029a14bc8f7a1e5859499 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 20 Mar 2026 18:36:07 -1000 Subject: [PATCH] [core] Reduce automation call chain stack depth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Force-inline the Trigger→Automation→ActionList forwarding chain and override play_complex() in leaf action classes to skip the virtual play() dispatch, reducing the button→lambda call stack from 8 frames to ~4. --- esphome/core/automation.h | 6 +++--- esphome/core/base_automation.h | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/esphome/core/automation.h b/esphome/core/automation.h index 7934fdbec97..4bc4bdf71e0 100644 --- a/esphome/core/automation.h +++ b/esphome/core/automation.h @@ -322,7 +322,7 @@ template class Automation; template class Trigger { public: /// Inform the parent automation that the event has triggered. - void trigger(const Ts &...x) { + __attribute__((always_inline)) void trigger(const Ts &...x) { if (this->automation_parent_ == nullptr) return; this->automation_parent_->trigger(x...); @@ -429,7 +429,7 @@ template class ActionList { this->add_action(action); } } - void play(const Ts &...x) { + __attribute__((always_inline)) void play(const Ts &...x) { if (this->actions_begin_ != nullptr) this->actions_begin_->play_complex(x...); } @@ -473,7 +473,7 @@ template class Automation { void stop() { this->actions_.stop(); } - void trigger(const Ts &...x) { this->actions_.play(x...); } + __attribute__((always_inline)) void trigger(const Ts &...x) { this->actions_.play(x...); } bool is_running() { return this->actions_.is_running(); } diff --git a/esphome/core/base_automation.h b/esphome/core/base_automation.h index 985f26e7116..6690c7d236e 100644 --- a/esphome/core/base_automation.h +++ b/esphome/core/base_automation.h @@ -217,6 +217,11 @@ template class LambdaAction : public Action { public: explicit LambdaAction(std::function &&f) : f_(std::move(f)) {} + void play_complex(const Ts &...x) override { + this->num_running_++; + this->f_(x...); + this->play_next_(x...); + } void play(const Ts &...x) override { this->f_(x...); } protected: @@ -230,6 +235,11 @@ template class StatelessLambdaAction : public Action { public: explicit StatelessLambdaAction(void (*f)(Ts...)) : f_(f) {} + void play_complex(const Ts &...x) override { + this->num_running_++; + this->f_(x...); + this->play_next_(x...); + } void play(const Ts &...x) override { this->f_(x...); } protected: @@ -243,6 +253,11 @@ template class ContinuationAction : public Action { public: explicit ContinuationAction(Action *parent) : parent_(parent) {} + void play_complex(const Ts &...x) override { + this->num_running_++; + this->parent_->play_next_(x...); + this->play_next_(x...); + } void play(const Ts &...x) override { this->parent_->play_next_(x...); } protected: