libexpr associate caches and statistics with EvalContext

Change-Id: Ie4740070881bdd056b112ffd79634e30c29e8aaa
This commit is contained in:
eldritch horrors 2024-12-03 20:38:41 +01:00
parent 71c392ae0f
commit 07a26fc776
3 changed files with 37 additions and 37 deletions

View file

@ -767,7 +767,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
forceAttrs(*env->values[0], fromWith->pos, "while evaluating the first subexpression of a with expression");
Bindings::iterator j = env->values[0]->attrs->find(var.name);
if (j != env->values[0]->attrs->end()) {
if (stats.countCalls) stats.attrSelects[j->pos]++;
if (ctx.stats.countCalls) ctx.stats.attrSelects[j->pos]++;
return j->value;
}
if (!fromWith->parentWith)
@ -891,7 +891,7 @@ Value * Expr::maybeThunk(EvalState & state, Env & env)
{
Value * v = state.ctx.mem.allocValue();
v->mkThunk(&env, *this);
state.stats.nrThunks++;
state.ctx.stats.nrThunks++;
return v;
}
@ -901,32 +901,32 @@ Value * ExprVar::maybeThunk(EvalState & state, Env & env)
Value * v = state.lookupVar(&env, *this, true);
/* The value might not be initialised in the environment yet.
In that case, ignore it. */
if (v) { state.stats.nrAvoided++; return v; }
if (v) { state.ctx.stats.nrAvoided++; return v; }
return Expr::maybeThunk(state, env);
}
Value * ExprString::maybeThunk(EvalState & state, Env & env)
{
state.stats.nrAvoided++;
state.ctx.stats.nrAvoided++;
return &v;
}
Value * ExprInt::maybeThunk(EvalState & state, Env & env)
{
state.stats.nrAvoided++;
state.ctx.stats.nrAvoided++;
return &v;
}
Value * ExprFloat::maybeThunk(EvalState & state, Env & env)
{
state.stats.nrAvoided++;
state.ctx.stats.nrAvoided++;
return &v;
}
Value * ExprPath::maybeThunk(EvalState & state, Env & env)
{
state.stats.nrAvoided++;
state.ctx.stats.nrAvoided++;
return &v;
}
@ -941,13 +941,13 @@ void EvalState::evalFile(const SourcePath & path_, Value & v)
{
auto path = ctx.paths.checkSourcePath(path_);
if (auto i = caches.fileEval.find(path); i != caches.fileEval.end()) {
if (auto i = ctx.caches.fileEval.find(path); i != ctx.caches.fileEval.end()) {
v = i->second->result;
return;
}
auto resolvedPath = resolveExprPath(path);
if (auto i = caches.fileEval.find(resolvedPath); i != caches.fileEval.end()) {
if (auto i = ctx.caches.fileEval.find(resolvedPath); i != ctx.caches.fileEval.end()) {
v = i->second->result;
return;
}
@ -972,14 +972,14 @@ void EvalState::evalFile(const SourcePath & path_, Value & v)
}
auto cache = std::allocate_shared<CachedEvalFile>(TraceableAllocator<CachedEvalFile>(), v);
caches.fileEval[resolvedPath] = cache;
if (path != resolvedPath) caches.fileEval[path] = cache;
ctx.caches.fileEval[resolvedPath] = cache;
if (path != resolvedPath) ctx.caches.fileEval[path] = cache;
}
void EvalState::resetFileCache()
{
caches.fileEval.clear();
ctx.caches.fileEval.clear();
}
@ -1091,7 +1091,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
if (hasOverrides && i.second.kind != AttrDef::Kind::Inherited) {
vAttr = state.ctx.mem.allocValue();
vAttr->mkThunk(i.second.chooseByKind(&env2, &env, inheritEnv), *i.second.e);
state.stats.nrThunks++;
state.ctx.stats.nrThunks++;
} else
vAttr = i.second.e->maybeThunk(state, *i.second.chooseByKind(&env2, &env, inheritEnv));
env2.values[displ++] = vAttr;
@ -1272,7 +1272,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
: nullptr;
for (auto const & [partIdx, currentAttrName] : enumerate(attrPath)) {
state.stats.nrLookups++;
state.ctx.stats.nrLookups++;
Symbol const name = getName(currentAttrName, state, env);
@ -1359,7 +1359,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
// Set our currently operated-on attrset to this one, and keep going.
vCurrent = attrIt->value;
posCurrent = attrIt->pos;
if (state.stats.countCalls) state.stats.attrSelects[posCurrent]++;
if (state.ctx.stats.countCalls) state.ctx.stats.attrSelects[posCurrent]++;
}
state.forceValue(*vCurrent, (posCurrent ? posCurrent : this->pos));
@ -1570,8 +1570,8 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
}
stats.nrFunctionCalls++;
if (stats.countCalls) stats.addCall(lambda);
ctx.stats.nrFunctionCalls++;
if (ctx.stats.countCalls) ctx.stats.addCall(lambda);
/* Evaluate the body. */
try {
@ -1610,8 +1610,8 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
/* We have all the arguments, so call the primop. */
auto * fn = vCur.primOp;
stats.nrPrimOpCalls++;
if (stats.countCalls) stats.primOpCalls[fn->name]++;
ctx.stats.nrPrimOpCalls++;
if (ctx.stats.countCalls) ctx.stats.primOpCalls[fn->name]++;
try {
fn->fun(*this, vCur.determinePos(noPos), args, vCur);
@ -1664,8 +1664,8 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
vArgs[argsDone + i] = args[i];
auto fn = primOp->primOp;
stats.nrPrimOpCalls++;
if (stats.countCalls) stats.primOpCalls[fn->name]++;
ctx.stats.nrPrimOpCalls++;
if (ctx.stats.countCalls) ctx.stats.primOpCalls[fn->name]++;
try {
// TODO:
@ -1875,7 +1875,7 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
state.evalAttrs(env, *e1, v1, pos, "in the left operand of the update (//) operator");
state.evalAttrs(env, *e2, v2, pos, "in the right operand of the update (//) operator");
state.stats.nrOpUpdates++;
state.ctx.stats.nrOpUpdates++;
if (v1.attrs->size() == 0) { v = v2; return; }
if (v2.attrs->size() == 0) { v = v1; return; }
@ -1903,7 +1903,7 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
v.mkAttrs(attrs.alreadySorted());
state.stats.nrOpUpdateValuesCopied += v.attrs->size();
state.ctx.stats.nrOpUpdateValuesCopied += v.attrs->size();
}
@ -1918,7 +1918,7 @@ void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
void EvalState::concatLists(Value & v, size_t nrLists, Value * * lists, const PosIdx pos, std::string_view errorCtx)
{
stats.nrListConcats++;
ctx.stats.nrListConcats++;
Value * nonEmpty = 0;
size_t len = 0;

View file

@ -791,14 +791,14 @@ void callFlake(EvalState & state,
vRootSubdir->mkString(lockedFlake.flake.lockedRef.subdir);
if (!state.caches.vCallFlake) {
state.caches.vCallFlake = allocRootValue(state.ctx.mem.allocValue());
if (!state.ctx.caches.vCallFlake) {
state.ctx.caches.vCallFlake = allocRootValue(state.ctx.mem.allocValue());
state.eval(state.ctx.parseExprFromString(
#include "call-flake.nix.gen.hh"
, CanonPath::root), **state.caches.vCallFlake);
, CanonPath::root), **state.ctx.caches.vCallFlake);
}
state.callFunction(**state.caches.vCallFlake, *vLocks, *vTmp1, noPos);
state.callFunction(**state.ctx.caches.vCallFlake, *vLocks, *vTmp1, noPos);
state.callFunction(*vTmp1, *vRootSrc, *vTmp2, noPos);
state.callFunction(*vTmp2, *vRootSubdir, vRes, noPos);
}

View file

@ -206,19 +206,19 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
auto w = state.ctx.mem.allocValue();
w->mkAttrs(attrs);
if (!state.caches.vImportedDrvToDerivation) {
state.caches.vImportedDrvToDerivation = allocRootValue(state.ctx.mem.allocValue());
if (!state.ctx.caches.vImportedDrvToDerivation) {
state.ctx.caches.vImportedDrvToDerivation = allocRootValue(state.ctx.mem.allocValue());
state.eval(state.ctx.parseExprFromString(
#include "imported-drv-to-derivation.nix.gen.hh"
, CanonPath::root), **state.caches.vImportedDrvToDerivation);
, CanonPath::root), **state.ctx.caches.vImportedDrvToDerivation);
}
state.forceFunction(
**state.caches.vImportedDrvToDerivation,
**state.ctx.caches.vImportedDrvToDerivation,
pos,
"while evaluating imported-drv-to-derivation.nix.gen.hh"
);
v.mkApp(*state.caches.vImportedDrvToDerivation, w);
v.mkApp(*state.ctx.caches.vImportedDrvToDerivation, w);
state.forceAttrs(v, pos, "while calling imported-drv-to-derivation.nix.gen.hh");
}
@ -1671,7 +1671,7 @@ void prim_getAttr(EvalState & state, const PosIdx pos, Value * * args, Value & v
"in the attribute set under consideration"
);
// !!! add to stack trace?
if (state.stats.countCalls && i->pos) state.stats.attrSelects[i->pos]++;
if (state.ctx.stats.countCalls && i->pos) state.ctx.stats.attrSelects[i->pos]++;
state.forceValue(*i->value, pos);
v = *i->value;
}
@ -2550,10 +2550,10 @@ struct RegexCache
static RegexCache & regexCacheOf(EvalState & state)
{
if (!state.caches.regexes) {
state.caches.regexes = std::make_shared<RegexCache>();
if (!state.ctx.caches.regexes) {
state.ctx.caches.regexes = std::make_shared<RegexCache>();
}
return *state.caches.regexes;
return *state.ctx.caches.regexes;
}
void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)