libexpr: move runtime caches to new struct
Change-Id: Ic5492853d39eaffdf03d961b3e69c93c4a75ae33
This commit is contained in:
parent
2e5780ebc8
commit
0bfa58ff53
|
@ -290,7 +290,6 @@ EvalState::EvalState(
|
||||||
, repair(NoRepair)
|
, repair(NoRepair)
|
||||||
, store(store)
|
, store(store)
|
||||||
, buildStore(buildStore ? buildStore : store)
|
, buildStore(buildStore ? buildStore : store)
|
||||||
, regexCache(makeRegexCache())
|
|
||||||
{
|
{
|
||||||
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
|
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
|
||||||
|
|
||||||
|
@ -911,19 +910,24 @@ Value * ExprPath::maybeThunk(EvalState & state, Env & env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct CachedEvalFile
|
||||||
|
{
|
||||||
|
Value result;
|
||||||
|
explicit CachedEvalFile(Value result): result(result) {}
|
||||||
|
};
|
||||||
|
|
||||||
void EvalState::evalFile(const SourcePath & path_, Value & v)
|
void EvalState::evalFile(const SourcePath & path_, Value & v)
|
||||||
{
|
{
|
||||||
auto path = checkSourcePath(path_);
|
auto path = checkSourcePath(path_);
|
||||||
|
|
||||||
FileEvalCache::iterator i;
|
if (auto i = caches.fileEval.find(path); i != caches.fileEval.end()) {
|
||||||
if ((i = fileEvalCache.find(path)) != fileEvalCache.end()) {
|
v = i->second->result;
|
||||||
v = i->second;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolvedPath = resolveExprPath(path);
|
auto resolvedPath = resolveExprPath(path);
|
||||||
if ((i = fileEvalCache.find(resolvedPath)) != fileEvalCache.end()) {
|
if (auto i = caches.fileEval.find(resolvedPath); i != caches.fileEval.end()) {
|
||||||
v = i->second;
|
v = i->second->result;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,14 +950,15 @@ void EvalState::evalFile(const SourcePath & path_, Value & v)
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileEvalCache[resolvedPath] = v;
|
auto cache = std::allocate_shared<CachedEvalFile>(TraceableAllocator<CachedEvalFile>(), v);
|
||||||
if (path != resolvedPath) fileEvalCache[path] = v;
|
caches.fileEval[resolvedPath] = cache;
|
||||||
|
if (path != resolvedPath) caches.fileEval[path] = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::resetFileCache()
|
void EvalState::resetFileCache()
|
||||||
{
|
{
|
||||||
fileEvalCache.clear();
|
caches.fileEval.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -130,8 +130,6 @@ void initLibExpr();
|
||||||
|
|
||||||
struct RegexCache;
|
struct RegexCache;
|
||||||
|
|
||||||
std::shared_ptr<RegexCache> makeRegexCache();
|
|
||||||
|
|
||||||
struct DebugTrace {
|
struct DebugTrace {
|
||||||
std::shared_ptr<Pos> pos;
|
std::shared_ptr<Pos> pos;
|
||||||
const Expr & expr;
|
const Expr & expr;
|
||||||
|
@ -326,6 +324,24 @@ public:
|
||||||
std::optional<Doc> getDoc(Value & v);
|
std::optional<Doc> getDoc(Value & v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CachedEvalFile;
|
||||||
|
|
||||||
|
struct EvalRuntimeCaches
|
||||||
|
{
|
||||||
|
RootValue vCallFlake;
|
||||||
|
RootValue vImportedDrvToDerivation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache used by prim_match() and other regex functions.
|
||||||
|
*/
|
||||||
|
std::shared_ptr<RegexCache> regexes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cache from path names to values for evalFile().
|
||||||
|
*/
|
||||||
|
std::map<SourcePath, std::shared_ptr<CachedEvalFile>> fileEval;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class EvalState
|
class EvalState
|
||||||
{
|
{
|
||||||
|
@ -336,6 +352,7 @@ public:
|
||||||
PosTable positions;
|
PosTable positions;
|
||||||
const StaticSymbols s;
|
const StaticSymbols s;
|
||||||
EvalMemory mem;
|
EvalMemory mem;
|
||||||
|
EvalRuntimeCaches caches;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SearchPath searchPath;
|
SearchPath searchPath;
|
||||||
|
@ -365,9 +382,6 @@ public:
|
||||||
*/
|
*/
|
||||||
const ref<Store> buildStore;
|
const ref<Store> buildStore;
|
||||||
|
|
||||||
RootValue vCallFlake = nullptr;
|
|
||||||
RootValue vImportedDrvToDerivation = nullptr;
|
|
||||||
|
|
||||||
std::unique_ptr<DebugState> debug;
|
std::unique_ptr<DebugState> debug;
|
||||||
|
|
||||||
template<class T, typename... Args>
|
template<class T, typename... Args>
|
||||||
|
@ -383,12 +397,6 @@ private:
|
||||||
paths. */
|
paths. */
|
||||||
std::map<SourcePath, StorePath> srcToStore;
|
std::map<SourcePath, StorePath> srcToStore;
|
||||||
|
|
||||||
/**
|
|
||||||
* A cache from path names to values.
|
|
||||||
*/
|
|
||||||
using FileEvalCache = GcMap<SourcePath, Value>;
|
|
||||||
FileEvalCache fileEvalCache;
|
|
||||||
|
|
||||||
std::map<std::string, std::optional<std::string>> searchPathResolved;
|
std::map<std::string, std::optional<std::string>> searchPathResolved;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -396,11 +404,6 @@ private:
|
||||||
*/
|
*/
|
||||||
std::unordered_map<Path, SourcePath> resolvedPaths;
|
std::unordered_map<Path, SourcePath> resolvedPaths;
|
||||||
|
|
||||||
/**
|
|
||||||
* Cache used by prim_match().
|
|
||||||
*/
|
|
||||||
std::shared_ptr<RegexCache> regexCache;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EvalState(
|
EvalState(
|
||||||
|
|
|
@ -791,14 +791,14 @@ void callFlake(EvalState & state,
|
||||||
|
|
||||||
vRootSubdir->mkString(lockedFlake.flake.lockedRef.subdir);
|
vRootSubdir->mkString(lockedFlake.flake.lockedRef.subdir);
|
||||||
|
|
||||||
if (!state.vCallFlake) {
|
if (!state.caches.vCallFlake) {
|
||||||
state.vCallFlake = allocRootValue(state.mem.allocValue());
|
state.caches.vCallFlake = allocRootValue(state.mem.allocValue());
|
||||||
state.eval(state.parseExprFromString(
|
state.eval(state.parseExprFromString(
|
||||||
#include "call-flake.nix.gen.hh"
|
#include "call-flake.nix.gen.hh"
|
||||||
, CanonPath::root), **state.vCallFlake);
|
, CanonPath::root), **state.caches.vCallFlake);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.callFunction(**state.vCallFlake, *vLocks, *vTmp1, noPos);
|
state.callFunction(**state.caches.vCallFlake, *vLocks, *vTmp1, noPos);
|
||||||
state.callFunction(*vTmp1, *vRootSrc, *vTmp2, noPos);
|
state.callFunction(*vTmp1, *vRootSrc, *vTmp2, noPos);
|
||||||
state.callFunction(*vTmp2, *vRootSubdir, vRes, noPos);
|
state.callFunction(*vTmp2, *vRootSubdir, vRes, noPos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,15 +206,19 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
|
||||||
auto w = state.mem.allocValue();
|
auto w = state.mem.allocValue();
|
||||||
w->mkAttrs(attrs);
|
w->mkAttrs(attrs);
|
||||||
|
|
||||||
if (!state.vImportedDrvToDerivation) {
|
if (!state.caches.vImportedDrvToDerivation) {
|
||||||
state.vImportedDrvToDerivation = allocRootValue(state.mem.allocValue());
|
state.caches.vImportedDrvToDerivation = allocRootValue(state.mem.allocValue());
|
||||||
state.eval(state.parseExprFromString(
|
state.eval(state.parseExprFromString(
|
||||||
#include "imported-drv-to-derivation.nix.gen.hh"
|
#include "imported-drv-to-derivation.nix.gen.hh"
|
||||||
, CanonPath::root), **state.vImportedDrvToDerivation);
|
, CanonPath::root), **state.caches.vImportedDrvToDerivation);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.forceFunction(**state.vImportedDrvToDerivation, pos, "while evaluating imported-drv-to-derivation.nix.gen.hh");
|
state.forceFunction(
|
||||||
v.mkApp(*state.vImportedDrvToDerivation, w);
|
**state.caches.vImportedDrvToDerivation,
|
||||||
|
pos,
|
||||||
|
"while evaluating imported-drv-to-derivation.nix.gen.hh"
|
||||||
|
);
|
||||||
|
v.mkApp(*state.caches.vImportedDrvToDerivation, w);
|
||||||
state.forceAttrs(v, pos, "while calling imported-drv-to-derivation.nix.gen.hh");
|
state.forceAttrs(v, pos, "while calling imported-drv-to-derivation.nix.gen.hh");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2543,9 +2547,12 @@ struct RegexCache
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<RegexCache> makeRegexCache()
|
static RegexCache & regexCacheOf(EvalState & state)
|
||||||
{
|
{
|
||||||
return std::make_shared<RegexCache>();
|
if (!state.caches.regexes) {
|
||||||
|
state.caches.regexes = std::make_shared<RegexCache>();
|
||||||
|
}
|
||||||
|
return *state.caches.regexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
|
@ -2554,7 +2561,7 @@ void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
auto regex = state.regexCache->get(re);
|
auto regex = regexCacheOf(state).get(re);
|
||||||
|
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.match");
|
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.match");
|
||||||
|
@ -2596,7 +2603,7 @@ void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
auto regex = state.regexCache->get(re);
|
auto regex = regexCacheOf(state).get(re);
|
||||||
|
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.split");
|
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.split");
|
||||||
|
|
Loading…
Reference in a new issue