@@ -194,6 +194,15 @@ static Symbol getName(const AttrName & name, EvalState & state, Env & env)
194194
195195static constexpr size_t BASE_ENV_SIZE = 128 ;
196196
197+ EvalMemory::EvalMemory ()
198+ #if NIX_USE_BOEHMGC
199+ : valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr ))
200+ , env1AllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr ))
201+ #endif
202+ {
203+ assertGCInitialized ();
204+ }
205+
197206EvalState::EvalState (
198207 const LookupPath & lookupPathFromArguments,
199208 ref<Store> store,
@@ -273,23 +282,14 @@ EvalState::EvalState(
273282 , importResolutionCache(make_ref<decltype (importResolutionCache)::element_type>())
274283 , fileEvalCache(make_ref<decltype (fileEvalCache)::element_type>())
275284 , regexCache(makeRegexCache())
276- #if NIX_USE_BOEHMGC
277- , valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr ))
278- , env1AllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr ))
279- , baseEnvP(std::allocate_shared<Env *>(traceable_allocator<Env *>(), &allocEnv (BASE_ENV_SIZE)))
280- , baseEnv(**baseEnvP)
281- #else
282- , baseEnv(allocEnv(BASE_ENV_SIZE))
283- #endif
285+ , baseEnv(mem.allocEnv(BASE_ENV_SIZE))
284286 , staticBaseEnv{std::make_shared<StaticEnv>(nullptr , nullptr )}
285287{
286288 corepkgsFS->setPathDisplay (" <nix" , " >" );
287289 internalFS->setPathDisplay (" «nix-internal»" , " " );
288290
289291 countCalls = getEnv (" NIX_COUNT_CALLS" ).value_or (" 0" ) != " 0" ;
290292
291- assertGCInitialized ();
292-
293293 static_assert (sizeof (Env) <= 16 , " environment must be <= 16 bytes" );
294294 static_assert (sizeof (Counter) == 64 , " counters must be 64 bytes" );
295295
@@ -423,7 +423,7 @@ void EvalState::checkURI(const std::string & uri)
423423
424424Value * EvalState::addConstant (const std::string & name, Value & v, Constant info)
425425{
426- Value * v2 = allocValue ();
426+ Value * v2 = mem. allocValue ();
427427 *v2 = v;
428428 addConstant (name, v2, info);
429429 return v2;
@@ -489,7 +489,7 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
489489 the primop to a dummy value. */
490490 if (primOp.arity == 0 ) {
491491 primOp.arity = 1 ;
492- auto vPrimOp = allocValue ();
492+ auto vPrimOp = mem. allocValue ();
493493 vPrimOp->mkPrimOp (new PrimOp (primOp));
494494 Value v;
495495 v.mkApp (vPrimOp, vPrimOp);
@@ -506,7 +506,7 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
506506 if (hasPrefix (primOp.name , " __" ))
507507 primOp.name = primOp.name .substr (2 );
508508
509- Value * v = allocValue ();
509+ Value * v = mem. allocValue ();
510510 v->mkPrimOp (new PrimOp (primOp));
511511
512512 if (primOp.internal )
@@ -885,11 +885,10 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
885885 }
886886}
887887
888- ListBuilder::ListBuilder (EvalState & state, size_t size)
888+ ListBuilder::ListBuilder (size_t size)
889889 : size(size)
890890 , elems(size <= 2 ? inlineElems : (Value **) allocBytes(size * sizeof (Value *)))
891891{
892- state.nrListElems += size;
893892}
894893
895894Value * EvalState::getBool (bool b)
@@ -990,7 +989,7 @@ void EvalState::mkSingleDerivedPathString(const SingleDerivedPath & p, Value & v
990989
991990Value * Expr::maybeThunk (EvalState & state, Env & env)
992991{
993- Value * v = state.allocValue ();
992+ Value * v = state.mem . allocValue ();
994993 mkThunk (*v, env, this );
995994 return v;
996995}
@@ -1100,7 +1099,7 @@ void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial)
11001099 *resolvedPath,
11011100 nullptr ,
11021101 [&](auto & i) {
1103- vExpr = allocValue ();
1102+ vExpr = mem. allocValue ();
11041103 vExpr->mkThunk (&baseEnv, expr);
11051104 i.second = vExpr;
11061105 },
@@ -1183,7 +1182,7 @@ void ExprPath::eval(EvalState & state, Env & env, Value & v)
11831182
11841183Env * ExprAttrs::buildInheritFromEnv (EvalState & state, Env & up)
11851184{
1186- Env & inheritEnv = state.allocEnv (inheritFromExprs->size ());
1185+ Env & inheritEnv = state.mem . allocEnv (inheritFromExprs->size ());
11871186 inheritEnv.up = &up;
11881187
11891188 Displacement displ = 0 ;
@@ -1202,7 +1201,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
12021201 if (recursive) {
12031202 /* Create a new environment that contains the attributes in
12041203 this `rec'. */
1205- Env & env2 (state.allocEnv (attrs.size ()));
1204+ Env & env2 (state.mem . allocEnv (attrs.size ()));
12061205 env2.up = &env;
12071206 dynamicEnv = &env2;
12081207 Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv (state, env2) : nullptr ;
@@ -1217,7 +1216,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
12171216 for (auto & i : attrs) {
12181217 Value * vAttr;
12191218 if (hasOverrides && i.second .kind != AttrDef::Kind::Inherited) {
1220- vAttr = state.allocValue ();
1219+ vAttr = state.mem . allocValue ();
12211220 mkThunk (*vAttr, *i.second .chooseByKind (&env2, &env, inheritEnv), i.second .e );
12221221 } else
12231222 vAttr = i.second .e ->maybeThunk (state, *i.second .chooseByKind (&env2, &env, inheritEnv));
@@ -1294,7 +1293,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
12941293{
12951294 /* Create a new environment that contains the attributes in this
12961295 `let'. */
1297- Env & env2 (state.allocEnv (attrs->attrs .size ()));
1296+ Env & env2 (state.mem . allocEnv (attrs->attrs .size ()));
12981297 env2.up = &env;
12991298
13001299 Env * inheritEnv = attrs->inheritFromExprs ? attrs->buildInheritFromEnv (state, env2) : nullptr ;
@@ -1485,7 +1484,7 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
14851484 auto makeAppChain = [&]() {
14861485 vRes = vCur;
14871486 for (auto arg : args) {
1488- auto fun2 = allocValue ();
1487+ auto fun2 = mem. allocValue ();
14891488 *fun2 = vRes;
14901489 vRes.mkPrimOpApp (fun2, arg);
14911490 }
@@ -1500,7 +1499,7 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
15001499 ExprLambda & lambda (*vCur.lambda ().fun );
15011500
15021501 auto size = (!lambda.arg ? 0 : 1 ) + (lambda.hasFormals () ? lambda.formals ->formals .size () : 0 );
1503- Env & env2 (allocEnv (size));
1502+ Env & env2 (mem. allocEnv (size));
15041503 env2.up = vCur.lambda ().env ;
15051504
15061505 Displacement displ = 0 ;
@@ -1683,7 +1682,7 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
16831682 /* 'vCur' may be allocated on the stack of the calling
16841683 function, but for functors we may keep a reference, so
16851684 heap-allocate a copy and use that instead. */
1686- Value * args2[] = {allocValue (), args[0 ]};
1685+ Value * args2[] = {mem. allocValue (), args[0 ]};
16871686 *args2[0 ] = vCur;
16881687 try {
16891688 callFunction (*functor->value , args2, vCur, functor->pos );
@@ -1743,7 +1742,7 @@ void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res
17431742 if (fun.type () == nAttrs) {
17441743 auto found = fun.attrs ()->get (s.functor );
17451744 if (found) {
1746- Value * v = allocValue ();
1745+ Value * v = mem. allocValue ();
17471746 callFunction (*found->value , fun, *v, pos);
17481747 forceValue (*v, pos);
17491748 return autoCallFunction (args, *v, res);
@@ -1784,12 +1783,12 @@ values, or passed explicitly with '--arg' or '--argstr'. See
17841783 }
17851784 }
17861785
1787- callFunction (fun, allocValue ()->mkAttrs (attrs), res, pos);
1786+ callFunction (fun, mem. allocValue ()->mkAttrs (attrs), res, pos);
17881787}
17891788
17901789void ExprWith::eval (EvalState & state, Env & env, Value & v)
17911790{
1792- Env & env2 (state.allocEnv (1 ));
1791+ Env & env2 (state.mem . allocEnv (1 ));
17931792 env2.up = &env;
17941793 env2.values [0 ] = attrs->maybeThunk (state, env);
17951794
@@ -2916,10 +2915,12 @@ void EvalState::printStatistics()
29162915 std::chrono::microseconds cpuTimeDuration = getCpuUserTime ();
29172916 float cpuTime = std::chrono::duration_cast<std::chrono::duration<float >>(cpuTimeDuration).count ();
29182917
2919- uint64_t bEnvs = nrEnvs * sizeof (Env) + nrValuesInEnvs * sizeof (Value *);
2920- uint64_t bLists = nrListElems * sizeof (Value *);
2921- uint64_t bValues = nrValues * sizeof (Value);
2922- uint64_t bAttrsets = nrAttrsets * sizeof (Bindings) + nrAttrsInAttrsets * sizeof (Attr);
2918+ auto memstats = mem.getStats ();
2919+
2920+ uint64_t bEnvs = memstats.nrEnvs * sizeof (Env) + memstats.nrValuesInEnvs * sizeof (Value *);
2921+ uint64_t bLists = memstats.nrListElems * sizeof (Value *);
2922+ uint64_t bValues = memstats.nrValues * sizeof (Value);
2923+ uint64_t bAttrsets = memstats.nrAttrsets * sizeof (Bindings) + memstats.nrAttrsInAttrsets * sizeof (Attr);
29232924
29242925#if NIX_USE_BOEHMGC
29252926 GC_word heapSize, totalBytes;
@@ -2945,28 +2946,28 @@ void EvalState::printStatistics()
29452946#endif
29462947 };
29472948 topObj[" envs" ] = {
2948- {" number" , nrEnvs.load ()},
2949- {" elements" , nrValuesInEnvs.load ()},
2949+ {" number" , memstats. nrEnvs .load ()},
2950+ {" elements" , memstats. nrValuesInEnvs .load ()},
29502951 {" bytes" , bEnvs},
29512952 };
29522953 topObj[" nrExprs" ] = Expr::nrExprs.load ();
29532954 topObj[" list" ] = {
2954- {" elements" , nrListElems.load ()},
2955+ {" elements" , memstats. nrListElems .load ()},
29552956 {" bytes" , bLists},
29562957 {" concats" , nrListConcats.load ()},
29572958 };
29582959 topObj[" values" ] = {
2959- {" number" , nrValues.load ()},
2960+ {" number" , memstats. nrValues .load ()},
29602961 {" bytes" , bValues},
29612962 };
29622963 topObj[" symbols" ] = {
29632964 {" number" , symbols.size ()},
29642965 {" bytes" , symbols.totalSize ()},
29652966 };
29662967 topObj[" sets" ] = {
2967- {" number" , nrAttrsets.load ()},
2968+ {" number" , memstats. nrAttrsets .load ()},
29682969 {" bytes" , bAttrsets},
2969- {" elements" , nrAttrsInAttrsets.load ()},
2970+ {" elements" , memstats. nrAttrsInAttrsets .load ()},
29702971 };
29712972 topObj[" sizes" ] = {
29722973 {" Env" , sizeof (Env)},
0 commit comments