about summary refs log tree commit diff
path: root/src/nix/upgrade-nix.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2018-06-12T15·26+0200
committerEelco Dolstra <edolstra@gmail.com>2018-06-12T15·49+0200
commit0629601da1d163a059fa19004256961f8ecdeb78 (patch)
treeb69f528da3cfa0a33395216fc4224bb4a27f6af4 /src/nix/upgrade-nix.cc
parentc905d8b0a84877d3cab10d4a8b8ad81895a6500e (diff)
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.
Diffstat (limited to 'src/nix/upgrade-nix.cc')
-rw-r--r--src/nix/upgrade-nix.cc12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc
index 21892c31a893..e23ae792369c 100644
--- a/src/nix/upgrade-nix.cc
+++ b/src/nix/upgrade-nix.cc
@@ -118,13 +118,13 @@ struct CmdUpgradeNix : StoreCommand
         auto req = DownloadRequest("https://github.com/NixOS/nixpkgs/raw/master/nixos/modules/installer/tools/nix-fallback-paths.nix");
         auto res = getDownloader()->download(req);
 
-        EvalState state(Strings(), store);
-        auto v = state.allocValue();
-        state.eval(state.parseExprFromString(*res.data, "/no-such-path"), *v);
-        Bindings & bindings(*state.allocBindings(0));
-        auto v2 = findAlongAttrPath(state, settings.thisSystem, bindings, *v);
+        auto state = std::make_unique<EvalState>(Strings(), store);
+        auto v = state->allocValue();
+        state->eval(state->parseExprFromString(*res.data, "/no-such-path"), *v);
+        Bindings & bindings(*state->allocBindings(0));
+        auto v2 = findAlongAttrPath(*state, settings.thisSystem, bindings, *v);
 
-        return state.forceString(*v2);
+        return state->forceString(*v2);
     }
 };