From 137673de5610ce20d03a0a79e242eb64a5c0f615 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Mon, 4 Mar 2024 07:39:12 +0100 Subject: [PATCH] Merge pull request #9681 from edolstra/eval-optimisations Optimize empty list constants (cherry picked from commit 315aade89d00c692715e5953c36a1b7d6528b703) Change-Id: I0f28ef8a27ccedc45acf44243eec9dc35b733300 --- src/libexpr/eval.cc | 11 +++++++++++ src/libexpr/eval.hh | 5 +++++ src/libexpr/nixexpr.hh | 1 + 3 files changed, 17 insertions(+) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0fa686701..309b9f103 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -527,6 +527,8 @@ EvalState::EvalState( static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes"); + vEmptyList.mkList(0); + /* Initialise the Nix expression search path. */ if (!evalSettings.pureEval) { for (auto & i : _searchPath.elements) @@ -1405,6 +1407,15 @@ void ExprList::eval(EvalState & state, Env & env, Value & v) } +Value * ExprList::maybeThunk(EvalState & state, Env & env) +{ + if (elems.empty()) { + return &state.vEmptyList; + } + return Expr::maybeThunk(state, env); +} + + void ExprVar::eval(EvalState & state, Env & env, Value & v) { Value * v2 = state.lookupVar(&env, *this, false); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 6adf6d066..9cf50ba6c 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -218,6 +218,11 @@ public: Bindings emptyBindings; + /** + * Empty list constant. + */ + Value vEmptyList; + const SourcePath derivationInternal; /** diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 2b5b72bc0..b38f19b41 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -298,6 +298,7 @@ struct ExprList : Expr std::vector elems; ExprList() { }; COMMON_METHODS + Value * maybeThunk(EvalState & state, Env & env) override; PosIdx getPos() const override {