From 7ff3cc65e4badadc1d612ee9e0190aabafac8d98 Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Tue, 11 Nov 2025 17:48:07 +0100 Subject: [PATCH] move allocBytes() into EvalMemory --- src/libexpr/eval.cc | 27 +++++++++-------- src/libexpr/include/nix/expr/eval-inline.hh | 2 +- src/libexpr/include/nix/expr/eval.hh | 3 +- src/libexpr/include/nix/expr/value.hh | 9 +++--- src/libexpr/primops.cc | 33 +++++++++++---------- src/libexpr/primops/context.cc | 6 ++-- 6 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 8e74316ca..8b068e8c7 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -852,25 +852,26 @@ void Value::mkString(std::string_view s) mkStringNoCopy(StringData::make(s)); } -Value::StringWithContext::Context * Value::StringWithContext::Context::fromBuilder(const NixStringContext & context) +Value::StringWithContext::Context * +Value::StringWithContext::Context::fromBuilder(const NixStringContext & context, EvalMemory & mem) { if (context.empty()) return nullptr; - auto ctx = new (allocBytes(sizeof(Context) + context.size() * sizeof(value_type))) Context(context.size()); + auto ctx = new (mem.allocBytes(sizeof(Context) + context.size() * sizeof(value_type))) Context(context.size()); std::ranges::transform( context, ctx->elems, [](const NixStringContextElem & elt) { return &StringData::make(elt.to_string()); }); return ctx; } -void Value::mkString(std::string_view s, const NixStringContext & context) +void Value::mkString(std::string_view s, const NixStringContext & context, EvalMemory & mem) { - mkStringNoCopy(StringData::make(s), Value::StringWithContext::Context::fromBuilder(context)); + mkStringNoCopy(StringData::make(s), Value::StringWithContext::Context::fromBuilder(context, mem)); } -void Value::mkStringMove(const StringData & s, const NixStringContext & context) +void Value::mkStringMove(const StringData & s, const NixStringContext & context, EvalMemory & mem) { - mkStringNoCopy(s, Value::StringWithContext::Context::fromBuilder(context)); + mkStringNoCopy(s, Value::StringWithContext::Context::fromBuilder(context, mem)); } void Value::mkPath(const SourcePath & path) @@ -911,9 +912,9 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) } } -ListBuilder::ListBuilder(size_t size) +ListBuilder::ListBuilder(EvalMemory & mem, size_t size) : size(size) - , elems(size <= 2 ? inlineElems : (Value **) allocBytes(size * sizeof(Value *))) + , elems(size <= 2 ? inlineElems : (Value **) mem.allocBytes(size * sizeof(Value *))) { } @@ -953,7 +954,8 @@ void EvalState::mkStorePathString(const StorePath & p, Value & v) store->printStorePath(p), NixStringContext{ NixStringContextElem::Opaque{.path = p}, - }); + }, + mem); } std::string EvalState::mkOutputStringRaw( @@ -975,7 +977,7 @@ void EvalState::mkOutputString( std::optional optStaticOutputPath, const ExperimentalFeatureSettings & xpSettings) { - value.mkString(mkOutputStringRaw(b, optStaticOutputPath, xpSettings), NixStringContext{b}); + value.mkString(mkOutputStringRaw(b, optStaticOutputPath, xpSettings), NixStringContext{b}, mem); } std::string EvalState::mkSingleDerivedPathStringRaw(const SingleDerivedPath & p) @@ -1010,7 +1012,8 @@ void EvalState::mkSingleDerivedPathString(const SingleDerivedPath & p, Value & v mkSingleDerivedPathStringRaw(p), NixStringContext{ std::visit([](auto && v) -> NixStringContextElem { return v; }, p), - }); + }, + mem); } Value * Expr::maybeThunk(EvalState & state, Env & env) @@ -2143,7 +2146,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) tmp += part->size(); } *tmp = '\0'; - v.mkStringMove(resultStr, context); + v.mkStringMove(resultStr, context, state.mem); } } diff --git a/src/libexpr/include/nix/expr/eval-inline.hh b/src/libexpr/include/nix/expr/eval-inline.hh index 1320da914..e8aa380fd 100644 --- a/src/libexpr/include/nix/expr/eval-inline.hh +++ b/src/libexpr/include/nix/expr/eval-inline.hh @@ -12,7 +12,7 @@ namespace nix { * Note: Various places expect the allocated memory to be zeroed. */ [[gnu::always_inline]] -inline void * allocBytes(size_t n) +inline void * EvalMemory::allocBytes(size_t n) { void * p; #if NIX_USE_BOEHMGC diff --git a/src/libexpr/include/nix/expr/eval.hh b/src/libexpr/include/nix/expr/eval.hh index 0c7f9cf09..85cbffbe8 100644 --- a/src/libexpr/include/nix/expr/eval.hh +++ b/src/libexpr/include/nix/expr/eval.hh @@ -335,6 +335,7 @@ public: EvalMemory & operator=(const EvalMemory &) = delete; EvalMemory & operator=(EvalMemory &&) = delete; + inline void * allocBytes(size_t n); inline Value * allocValue(); inline Env & allocEnv(size_t size); @@ -348,7 +349,7 @@ public: ListBuilder buildList(size_t size) { stats.nrListElems += size; - return ListBuilder(size); + return ListBuilder(*this, size); } const Statistics & getStats() const & diff --git a/src/libexpr/include/nix/expr/value.hh b/src/libexpr/include/nix/expr/value.hh index 54a735fbd..ff62092f2 100644 --- a/src/libexpr/include/nix/expr/value.hh +++ b/src/libexpr/include/nix/expr/value.hh @@ -88,6 +88,7 @@ class PosIdx; struct Pos; class StorePath; class EvalState; +class EvalMemory; class XMLWriter; class Printer; @@ -161,7 +162,7 @@ class ListBuilder Value * inlineElems[2] = {nullptr, nullptr}; public: Value ** elems; - ListBuilder(size_t size); + ListBuilder(EvalMemory & mem, size_t size); // NOTE: Can be noexcept because we are just copying integral values and // raw pointers. @@ -364,7 +365,7 @@ struct ValueBase /** * @return null pointer when context.empty() */ - static Context * fromBuilder(const NixStringContext & context); + static Context * fromBuilder(const NixStringContext & context, EvalMemory & mem); }; /** @@ -1148,9 +1149,9 @@ public: void mkString(std::string_view s); - void mkString(std::string_view s, const NixStringContext & context); + void mkString(std::string_view s, const NixStringContext & context, EvalMemory & mem); - void mkStringMove(const StringData & s, const NixStringContext & context); + void mkStringMove(const StringData & s, const NixStringContext & context, EvalMemory & mem); void mkPath(const SourcePath & path); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 3b39b7f20..98ed1b450 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -222,7 +222,8 @@ void derivationToValue( path2, { NixStringContextElem::DrvDeep{.drvPath = storePath}, - }); + }, + state.mem); attrs.alloc(state.s.name).mkString(drv.env["name"]); auto list = state.buildList(drv.outputs.size()); @@ -1811,7 +1812,8 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName drvPathS, { NixStringContextElem::DrvDeep{.drvPath = drvPath}, - }); + }, + state.mem); for (auto & i : drv.outputs) mkOutputString(state, result, drvPath, i); @@ -1864,7 +1866,7 @@ static void prim_toPath(EvalState & state, const PosIdx pos, Value ** args, Valu NixStringContext context; auto path = state.coerceToPath(pos, *args[0], context, "while evaluating the first argument passed to builtins.toPath"); - v.mkString(path.path.abs(), context); + v.mkString(path.path.abs(), context, state.mem); } static RegisterPrimOp primop_toPath({ @@ -1907,7 +1909,7 @@ static void prim_storePath(EvalState & state, const PosIdx pos, Value ** args, V if (!settings.readOnlyMode) state.store->ensurePath(path2); context.insert(NixStringContextElem::Opaque{.path = path2}); - v.mkString(path.abs(), context); + v.mkString(path.abs(), context, state.mem); } static RegisterPrimOp primop_storePath({ @@ -1989,7 +1991,8 @@ static void prim_baseNameOf(EvalState & state, const PosIdx pos, Value ** args, v.mkString( legacyBaseNameOf(*state.coerceToString( pos, *args[0], context, "while evaluating the first argument passed to builtins.baseNameOf", false, false)), - context); + context, + state.mem); } static RegisterPrimOp primop_baseNameOf({ @@ -2025,11 +2028,11 @@ static void prim_dirOf(EvalState & state, const PosIdx pos, Value ** args, Value pos, *args[0], context, "while evaluating the first argument passed to 'builtins.dirOf'", false, false); auto pos = path->rfind('/'); if (pos == path->npos) - v.mkStringMove("."_sds, context); + v.mkStringMove("."_sds, context, state.mem); else if (pos == 0) - v.mkStringMove("/"_sds, context); + v.mkStringMove("/"_sds, context, state.mem); else - v.mkString(path->substr(0, pos), context); + v.mkString(path->substr(0, pos), context, state.mem); } } @@ -2071,7 +2074,7 @@ static void prim_readFile(EvalState & state, const PosIdx pos, Value ** args, Va .path = std::move((StorePath &&) p), }); } - v.mkString(s, context); + v.mkString(s, context, state.mem); } static RegisterPrimOp primop_readFile({ @@ -2467,7 +2470,7 @@ static void prim_toXML(EvalState & state, const PosIdx pos, Value ** args, Value std::ostringstream out; NixStringContext context; printValueAsXML(state, true, false, *args[0], out, context, pos); - v.mkString(out.view(), context); + v.mkString(out.view(), context, state.mem); } static RegisterPrimOp primop_toXML({ @@ -2575,7 +2578,7 @@ static void prim_toJSON(EvalState & state, const PosIdx pos, Value ** args, Valu std::ostringstream out; NixStringContext context; printValueAsJSON(state, true, *args[0], pos, out, context); - v.mkString(out.view(), context); + v.mkString(out.view(), context, state.mem); } static RegisterPrimOp primop_toJSON({ @@ -4404,7 +4407,7 @@ static void prim_toString(EvalState & state, const PosIdx pos, Value ** args, Va NixStringContext context; auto s = state.coerceToString( pos, *args[0], context, "while evaluating the first argument passed to builtins.toString", true, false); - v.mkString(*s, context); + v.mkString(*s, context, state.mem); } static RegisterPrimOp primop_toString({ @@ -4477,7 +4480,7 @@ static void prim_substring(EvalState & state, const PosIdx pos, Value ** args, V auto s = state.coerceToString( pos, *args[2], context, "while evaluating the third argument (the string) passed to builtins.substring"); - v.mkString(NixUInt(start) >= s->size() ? "" : s->substr(start, _len), context); + v.mkString(NixUInt(start) >= s->size() ? "" : s->substr(start, _len), context, state.mem); } static RegisterPrimOp primop_substring({ @@ -4875,7 +4878,7 @@ static void prim_concatStringsSep(EvalState & state, const PosIdx pos, Value ** "while evaluating one element of the list of strings to concat passed to builtins.concatStringsSep"); } - v.mkString(res, context); + v.mkString(res, context, state.mem); } static RegisterPrimOp primop_concatStringsSep({ @@ -4950,7 +4953,7 @@ static void prim_replaceStrings(EvalState & state, const PosIdx pos, Value ** ar } } - v.mkString(res, context); + v.mkString(res, context, state.mem); } static RegisterPrimOp primop_replaceStrings({ diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index 8a9fe42e8..2c5add148 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -69,7 +69,7 @@ static void prim_unsafeDiscardOutputDependency(EvalState & state, const PosIdx p } } - v.mkString(*s, context2); + v.mkString(*s, context2, state.mem); } static RegisterPrimOp primop_unsafeDiscardOutputDependency( @@ -137,7 +137,7 @@ static void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, V context.begin()->raw)}), }; - v.mkString(*s, context2); + v.mkString(*s, context2, state.mem); } static RegisterPrimOp primop_addDrvOutputDependencies( @@ -321,7 +321,7 @@ static void prim_appendContext(EvalState & state, const PosIdx pos, Value ** arg } } - v.mkString(orig, context); + v.mkString(orig, context, state.mem); } static RegisterPrimOp primop_appendContext({.name = "__appendContext", .arity = 2, .fun = prim_appendContext});