1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 06:31:14 +02:00

Move EvalState from the stack to the heap

EvalState contains a few counters (e.g. nrValues) that increase
quickly enough that they end up being interpreted as pointers by the
garbage collector. Moving it to the heap makes them invisible to the
garbage collector.

This reduces the max RSS doing 100 evaluations of
nixos.tests.firefox.x86_64-linux.drvPath from 455 MiB to 292 MiB.

Note: ideally, allocations would be much further up in the 64-bit
address space to reduce the odds of an integer being misinterpreted as
a pointer. Maybe we can use some linker magic to move the .bss segment
to a higher address.
This commit is contained in:
Eelco Dolstra 2018-06-12 17:26:36 +02:00
parent c905d8b0a8
commit 0629601da1
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 46 additions and 46 deletions

View file

@ -239,10 +239,10 @@ void mainWrapped(int argc, char * * argv)
auto store = openStore();
EvalState state(myArgs.searchPath, store);
state.repair = repair;
auto state = std::make_unique<EvalState>(myArgs.searchPath, store);
state->repair = repair;
Bindings & autoArgs = *myArgs.getAutoArgs(state);
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
if (packages) {
std::ostringstream joined;
@ -268,7 +268,7 @@ void mainWrapped(int argc, char * * argv)
std::vector<Expr *> exprs;
if (readStdin)
exprs = {state.parseStdin()};
exprs = {state->parseStdin()};
else
for (auto i : left) {
auto absolute = i;
@ -276,13 +276,13 @@ void mainWrapped(int argc, char * * argv)
absolute = canonPath(absPath(i), true);
} catch (Error e) {};
if (fromArgs)
exprs.push_back(state.parseExprFromString(i, absPath(".")));
exprs.push_back(state->parseExprFromString(i, absPath(".")));
else if (store->isStorePath(absolute) && std::regex_match(absolute, std::regex(".*\\.drv(!.*)?")))
drvs.push_back(DrvInfo(state, store, absolute));
drvs.push_back(DrvInfo(*state, store, absolute));
else
/* If we're in a #! script, interpret filenames
relative to the script. */
exprs.push_back(state.parseExprFromFile(resolveExprPath(state.checkSourcePath(lookupFileArg(state,
exprs.push_back(state->parseExprFromFile(resolveExprPath(state->checkSourcePath(lookupFileArg(*state,
inShebang && !packages ? absPath(i, absPath(dirOf(script))) : i)))));
}
@ -291,12 +291,12 @@ void mainWrapped(int argc, char * * argv)
for (auto e : exprs) {
Value vRoot;
state.eval(e, vRoot);
state->eval(e, vRoot);
for (auto & i : attrPaths) {
Value & v(*findAlongAttrPath(state, i, autoArgs, vRoot));
state.forceValue(v);
getDerivations(state, v, "", autoArgs, drvs, false);
Value & v(*findAlongAttrPath(*state, i, autoArgs, vRoot));
state->forceValue(v);
getDerivations(*state, v, "", autoArgs, drvs, false);
}
}
@ -332,12 +332,12 @@ void mainWrapped(int argc, char * * argv)
if (shell == "") {
try {
auto expr = state.parseExprFromString("(import <nixpkgs> {}).bashInteractive", absPath("."));
auto expr = state->parseExprFromString("(import <nixpkgs> {}).bashInteractive", absPath("."));
Value v;
state.eval(expr, v);
state->eval(expr, v);
auto drv = getDerivation(state, v, false);
auto drv = getDerivation(*state, v, false);
if (!drv)
throw Error("the 'bashInteractive' attribute in <nixpkgs> did not evaluate to a derivation");