From f017f9ddd336e32a5ed1ee835f1c6c7e73a052ae Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Wed, 27 Nov 2024 02:09:08 +0100 Subject: [PATCH] libexpr: extract some global constants from EvalState these do not rely on the GC being initialized. there's no reason for them to not be statics, shared between all eval states in a process. Change-Id: Ib9675f3945d3a0a7097d6c85096adcbd6f441d83 --- lix/libexpr/attr-set.cc | 3 ++- lix/libexpr/attr-set.hh | 2 ++ lix/libexpr/eval.cc | 5 +---- lix/libexpr/eval.hh | 7 ------- lix/libexpr/primops.cc | 4 ++-- lix/libexpr/value.cc | 2 ++ lix/libexpr/value.hh | 5 +++++ 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lix/libexpr/attr-set.cc b/lix/libexpr/attr-set.cc index 0c4240089..78cf87884 100644 --- a/lix/libexpr/attr-set.cc +++ b/lix/libexpr/attr-set.cc @@ -7,6 +7,7 @@ namespace nix { +Bindings Bindings::EMPTY{0}; /* Allocate a new array of attributes for an attribute set with a specific @@ -15,7 +16,7 @@ namespace nix { Bindings * EvalState::allocBindings(size_t capacity) { if (capacity == 0) - return &emptyBindings; + return &Bindings::EMPTY; if (capacity > std::numeric_limits::max()) throw Error("attribute set of size %d is too big", capacity); nrAttrsets++; diff --git a/lix/libexpr/attr-set.hh b/lix/libexpr/attr-set.hh index 186272995..f25d1545e 100644 --- a/lix/libexpr/attr-set.hh +++ b/lix/libexpr/attr-set.hh @@ -51,6 +51,8 @@ public: typedef uint32_t size_t; PosIdx pos; + static Bindings EMPTY; + private: size_t size_, capacity_; Attr attrs[0]; diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 79fc23dd7..360a492c8 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -255,7 +255,6 @@ EvalState::EvalState( .overrides = symbols.create("__overrides"), } , repair(NoRepair) - , emptyBindings(0) , derivationInternal(rootPath(CanonPath("/builtin/derivation.nix"))) , store(store) , buildStore(buildStore ? buildStore : store) @@ -276,8 +275,6 @@ 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) @@ -1200,7 +1197,7 @@ void ExprList::eval(EvalState & state, Env & env, Value & v) Value * ExprList::maybeThunk(EvalState & state, Env & env) { if (elems.empty()) { - return &state.vEmptyList; + return &Value::EMPTY_LIST; } return Expr::maybeThunk(state, env); } diff --git a/lix/libexpr/eval.hh b/lix/libexpr/eval.hh index e011db998..fec3b8c88 100644 --- a/lix/libexpr/eval.hh +++ b/lix/libexpr/eval.hh @@ -187,13 +187,6 @@ public: */ std::optional allowedPaths; - Bindings emptyBindings; - - /** - * Empty list constant. - */ - Value vEmptyList; - const SourcePath derivationInternal; /** diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index deb47c15a..b59141e46 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -1898,14 +1898,14 @@ static void prim_functionArgs(EvalState & state, const PosIdx pos, Value * * arg { state.forceValue(*args[0], pos); if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) { - v.mkAttrs(&state.emptyBindings); + v.mkAttrs(&Bindings::EMPTY); return; } if (!args[0]->isLambda()) state.error("'functionArgs' requires a function").atPos(pos).debugThrow(); if (!args[0]->lambda.fun->hasFormals()) { - v.mkAttrs(&state.emptyBindings); + v.mkAttrs(&Bindings::EMPTY); return; } diff --git a/lix/libexpr/value.cc b/lix/libexpr/value.cc index 1f8fe0566..9d293146f 100644 --- a/lix/libexpr/value.cc +++ b/lix/libexpr/value.cc @@ -9,6 +9,8 @@ namespace nix { +Value Value::EMPTY_LIST{Value::list_t{}, {}}; + static void copyContextToValue(Value & v, const NixStringContext & context) { if (!context.empty()) { diff --git a/lix/libexpr/value.hh b/lix/libexpr/value.hh index cad7c5da1..b69049130 100644 --- a/lix/libexpr/value.hh +++ b/lix/libexpr/value.hh @@ -197,6 +197,11 @@ private: public: + /** + * Empty list constant. + */ + static Value EMPTY_LIST; + // Discount `using NewValueAs::*;` // NOLINTNEXTLINE(bugprone-macro-parentheses) #define USING_VALUETYPE(name) using name = NewValueAs::name