aboutsummaryrefslogtreecommitdiff
path: root/src/nix
diff options
context:
space:
mode:
authorAndreas Rammhold <andreas@rammhold.de>2020-04-13 21:09:47 +0200
committerAndreas Rammhold <andreas@rammhold.de>2020-04-13 21:23:54 +0200
commitd2c371927e45c1d4e4f7e4ad331a3f68d67d5469 (patch)
treea3fc0397eb52caa7f407dca5bf02f4a8f83505b7 /src/nix
parent512753f8247b927b62fd9391ee5ba6dda29ea4d4 (diff)
SourceExprCommand: allocate the vSourceExpr via uncollectable memory
Previously the memory would occasionally be collected during eval since the GC doesn't consider the member variable as alive / doesn't scan the region of memory where the pointer lives. By using the traceable_allocator<T> allocator provided by Boehm GC we can ensure the memory isn't collected. It should be properly freed when SourceExprCommand goes out of scope.
Diffstat (limited to 'src/nix')
-rw-r--r--src/nix/command.hh2
-rw-r--r--src/nix/installables.cc12
2 files changed, 10 insertions, 4 deletions
diff --git a/src/nix/command.hh b/src/nix/command.hh
index 23f5c9898..2c2303208 100644
--- a/src/nix/command.hh
+++ b/src/nix/command.hh
@@ -41,7 +41,7 @@ private:
std::shared_ptr<EvalState> evalState;
- Value * vSourceExpr = 0;
+ std::shared_ptr<Value> vSourceExpr;
};
enum RealiseMode { Build, NoBuild, DryRun };
diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index f464d0aa1..902383bff 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -8,10 +8,13 @@
#include "store-api.hh"
#include "shared.hh"
+#include <gc/gc.h>
+
#include <regex>
namespace nix {
+
SourceExprCommand::SourceExprCommand()
{
mkFlag()
@@ -24,11 +27,14 @@ SourceExprCommand::SourceExprCommand()
Value * SourceExprCommand::getSourceExpr(EvalState & state)
{
- if (vSourceExpr) return vSourceExpr;
+ if (vSourceExpr) return vSourceExpr.get();
auto sToplevel = state.symbols.create("_toplevel");
- vSourceExpr = state.allocValue();
+ // Allocate the vSourceExpr Value as uncollectable. Boehm GC doesn't
+ // consider the member variable "alive" during execution causing it to be
+ // GC'ed in the middle of evaluation.
+ vSourceExpr = std::allocate_shared<Value>(traceable_allocator<Value>());
if (file != "")
state.evalFile(lookupFileArg(state, file), *vSourceExpr);
@@ -69,7 +75,7 @@ Value * SourceExprCommand::getSourceExpr(EvalState & state)
vSourceExpr->attrs->sort();
}
- return vSourceExpr;
+ return vSourceExpr.get();
}
ref<EvalState> SourceExprCommand::getEvalState()