@@ -193,6 +193,15 @@ static Symbol getName(const AttrName & name, EvalState & state, Env & env)
193193
194194static constexpr size_t BASE_ENV_SIZE = 128 ;
195195
196+ EvalMemory::EvalMemory ()
197+ #if NIX_USE_BOEHMGC
198+ : valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr ))
199+ , env1AllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr ))
200+ #endif
201+ {
202+ assertGCInitialized ();
203+ }
204+
196205EvalState::EvalState (
197206 const LookupPath & lookupPathFromArguments,
198207 ref<Store> store,
@@ -269,23 +278,14 @@ EvalState::EvalState(
269278 , importResolutionCache(make_ref<decltype (importResolutionCache)::element_type>())
270279 , fileEvalCache(make_ref<decltype (fileEvalCache)::element_type>())
271280 , regexCache(makeRegexCache())
272- #if NIX_USE_BOEHMGC
273- , valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr ))
274- , env1AllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr ))
275- , baseEnvP(std::allocate_shared<Env *>(traceable_allocator<Env *>(), &allocEnv (BASE_ENV_SIZE)))
276- , baseEnv(**baseEnvP)
277- #else
278- , baseEnv(allocEnv(BASE_ENV_SIZE))
279- #endif
281+ , baseEnv(mem.allocEnv(BASE_ENV_SIZE))
280282 , staticBaseEnv{std::make_shared<StaticEnv>(nullptr , nullptr )}
281283{
282284 corepkgsFS->setPathDisplay (" <nix" , " >" );
283285 internalFS->setPathDisplay (" «nix-internal»" , " " );
284286
285287 countCalls = getEnv (" NIX_COUNT_CALLS" ).value_or (" 0" ) != " 0" ;
286288
287- assertGCInitialized ();
288-
289289 static_assert (sizeof (Env) <= 16 , " environment must be <= 16 bytes" );
290290
291291 /* Construct the Nix expression search path. */
@@ -418,7 +418,7 @@ void EvalState::checkURI(const std::string & uri)
418418
419419Value * EvalState::addConstant (const std::string & name, Value & v, Constant info)
420420{
421- Value * v2 = allocValue ();
421+ Value * v2 = mem. allocValue ();
422422 *v2 = v;
423423 addConstant (name, v2, info);
424424 return v2;
@@ -484,7 +484,7 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
484484 the primop to a dummy value. */
485485 if (primOp.arity == 0 ) {
486486 primOp.arity = 1 ;
487- auto vPrimOp = allocValue ();
487+ auto vPrimOp = mem. allocValue ();
488488 vPrimOp->mkPrimOp (new PrimOp (primOp));
489489 Value v;
490490 v.mkApp (vPrimOp, vPrimOp);
@@ -501,7 +501,7 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
501501 if (hasPrefix (primOp.name , " __" ))
502502 primOp.name = primOp.name .substr (2 );
503503
504- Value * v = allocValue ();
504+ Value * v = mem. allocValue ();
505505 v->mkPrimOp (new PrimOp (primOp));
506506
507507 if (primOp.internal )
@@ -880,11 +880,10 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
880880 }
881881}
882882
883- ListBuilder::ListBuilder (EvalState & state, size_t size)
883+ ListBuilder::ListBuilder (size_t size)
884884 : size(size)
885885 , elems(size <= 2 ? inlineElems : (Value **) allocBytes(size * sizeof (Value *)))
886886{
887- state.nrListElems += size;
888887}
889888
890889Value * EvalState::getBool (bool b)
@@ -985,7 +984,7 @@ void EvalState::mkSingleDerivedPathString(const SingleDerivedPath & p, Value & v
985984
986985Value * Expr::maybeThunk (EvalState & state, Env & env)
987986{
988- Value * v = state.allocValue ();
987+ Value * v = state.mem . allocValue ();
989988 mkThunk (*v, env, this );
990989 return v;
991990}
@@ -1095,7 +1094,7 @@ void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial)
10951094 *resolvedPath,
10961095 nullptr ,
10971096 [&](auto & i) {
1098- vExpr = allocValue ();
1097+ vExpr = mem. allocValue ();
10991098 vExpr->mkThunk (&baseEnv, expr);
11001099 i.second = vExpr;
11011100 },
@@ -1178,7 +1177,7 @@ void ExprPath::eval(EvalState & state, Env & env, Value & v)
11781177
11791178Env * ExprAttrs::buildInheritFromEnv (EvalState & state, Env & up)
11801179{
1181- Env & inheritEnv = state.allocEnv (inheritFromExprs->size ());
1180+ Env & inheritEnv = state.mem . allocEnv (inheritFromExprs->size ());
11821181 inheritEnv.up = &up;
11831182
11841183 Displacement displ = 0 ;
@@ -1197,7 +1196,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
11971196 if (recursive) {
11981197 /* Create a new environment that contains the attributes in
11991198 this `rec'. */
1200- Env & env2 (state.allocEnv (attrs.size ()));
1199+ Env & env2 (state.mem . allocEnv (attrs.size ()));
12011200 env2.up = &env;
12021201 dynamicEnv = &env2;
12031202 Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv (state, env2) : nullptr ;
@@ -1212,7 +1211,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
12121211 for (auto & i : attrs) {
12131212 Value * vAttr;
12141213 if (hasOverrides && i.second .kind != AttrDef::Kind::Inherited) {
1215- vAttr = state.allocValue ();
1214+ vAttr = state.mem . allocValue ();
12161215 mkThunk (*vAttr, *i.second .chooseByKind (&env2, &env, inheritEnv), i.second .e );
12171216 } else
12181217 vAttr = i.second .e ->maybeThunk (state, *i.second .chooseByKind (&env2, &env, inheritEnv));
@@ -1289,7 +1288,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
12891288{
12901289 /* Create a new environment that contains the attributes in this
12911290 `let'. */
1292- Env & env2 (state.allocEnv (attrs->attrs .size ()));
1291+ Env & env2 (state.mem . allocEnv (attrs->attrs .size ()));
12931292 env2.up = &env;
12941293
12951294 Env * inheritEnv = attrs->inheritFromExprs ? attrs->buildInheritFromEnv (state, env2) : nullptr ;
@@ -1480,7 +1479,7 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
14801479 auto makeAppChain = [&]() {
14811480 vRes = vCur;
14821481 for (auto arg : args) {
1483- auto fun2 = allocValue ();
1482+ auto fun2 = mem. allocValue ();
14841483 *fun2 = vRes;
14851484 vRes.mkPrimOpApp (fun2, arg);
14861485 }
@@ -1495,7 +1494,7 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
14951494 ExprLambda & lambda (*vCur.lambda ().fun );
14961495
14971496 auto size = (!lambda.arg ? 0 : 1 ) + (lambda.hasFormals () ? lambda.formals ->formals .size () : 0 );
1498- Env & env2 (allocEnv (size));
1497+ Env & env2 (mem. allocEnv (size));
14991498 env2.up = vCur.lambda ().env ;
15001499
15011500 Displacement displ = 0 ;
@@ -1678,7 +1677,7 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
16781677 /* 'vCur' may be allocated on the stack of the calling
16791678 function, but for functors we may keep a reference, so
16801679 heap-allocate a copy and use that instead. */
1681- Value * args2[] = {allocValue (), args[0 ]};
1680+ Value * args2[] = {mem. allocValue (), args[0 ]};
16821681 *args2[0 ] = vCur;
16831682 try {
16841683 callFunction (*functor->value , args2, vCur, functor->pos );
@@ -1738,7 +1737,7 @@ void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res
17381737 if (fun.type () == nAttrs) {
17391738 auto found = fun.attrs ()->get (s.functor );
17401739 if (found) {
1741- Value * v = allocValue ();
1740+ Value * v = mem. allocValue ();
17421741 callFunction (*found->value , fun, *v, pos);
17431742 forceValue (*v, pos);
17441743 return autoCallFunction (args, *v, res);
@@ -1779,12 +1778,12 @@ values, or passed explicitly with '--arg' or '--argstr'. See
17791778 }
17801779 }
17811780
1782- callFunction (fun, allocValue ()->mkAttrs (attrs), res, pos);
1781+ callFunction (fun, mem. allocValue ()->mkAttrs (attrs), res, pos);
17831782}
17841783
17851784void ExprWith::eval (EvalState & state, Env & env, Value & v)
17861785{
1787- Env & env2 (state.allocEnv (1 ));
1786+ Env & env2 (state.mem . allocEnv (1 ));
17881787 env2.up = &env;
17891788 env2.values [0 ] = attrs->maybeThunk (state, env);
17901789
@@ -2883,10 +2882,12 @@ void EvalState::printStatistics()
28832882 std::chrono::microseconds cpuTimeDuration = getCpuUserTime ();
28842883 float cpuTime = std::chrono::duration_cast<std::chrono::duration<float >>(cpuTimeDuration).count ();
28852884
2886- uint64_t bEnvs = nrEnvs * sizeof (Env) + nrValuesInEnvs * sizeof (Value *);
2887- uint64_t bLists = nrListElems * sizeof (Value *);
2888- uint64_t bValues = nrValues * sizeof (Value);
2889- uint64_t bAttrsets = nrAttrsets * sizeof (Bindings) + nrAttrsInAttrsets * sizeof (Attr);
2885+ auto memstats = mem.getStats ();
2886+
2887+ uint64_t bEnvs = memstats.nrEnvs * sizeof (Env) + memstats.nrValuesInEnvs * sizeof (Value *);
2888+ uint64_t bLists = memstats.nrListElems * sizeof (Value *);
2889+ uint64_t bValues = memstats.nrValues * sizeof (Value);
2890+ uint64_t bAttrsets = memstats.nrAttrsets * sizeof (Bindings) + memstats.nrAttrsInAttrsets * sizeof (Attr);
28902891
28912892#if NIX_USE_BOEHMGC
28922893 GC_word heapSize, totalBytes;
@@ -2912,28 +2913,28 @@ void EvalState::printStatistics()
29122913#endif
29132914 };
29142915 topObj[" envs" ] = {
2915- {" number" , nrEnvs},
2916- {" elements" , nrValuesInEnvs},
2916+ {" number" , memstats. nrEnvs },
2917+ {" elements" , memstats. nrValuesInEnvs },
29172918 {" bytes" , bEnvs},
29182919 };
29192920 topObj[" nrExprs" ] = Expr::nrExprs;
29202921 topObj[" list" ] = {
2921- {" elements" , nrListElems},
2922+ {" elements" , memstats. nrListElems },
29222923 {" bytes" , bLists},
29232924 {" concats" , nrListConcats},
29242925 };
29252926 topObj[" values" ] = {
2926- {" number" , nrValues},
2927+ {" number" , memstats. nrValues },
29272928 {" bytes" , bValues},
29282929 };
29292930 topObj[" symbols" ] = {
29302931 {" number" , symbols.size ()},
29312932 {" bytes" , symbols.totalSize ()},
29322933 };
29332934 topObj[" sets" ] = {
2934- {" number" , nrAttrsets},
2935+ {" number" , memstats. nrAttrsets },
29352936 {" bytes" , bAttrsets},
2936- {" elements" , nrAttrsInAttrsets},
2937+ {" elements" , memstats. nrAttrsInAttrsets },
29372938 };
29382939 topObj[" sizes" ] = {
29392940 {" Env" , sizeof (Env)},
0 commit comments