diff options
author | Andreas Rammhold <andreas@rammhold.de> | 2020-04-13 21:09:47 +0200 |
---|---|---|
committer | Andreas Rammhold <andreas@rammhold.de> | 2020-04-13 21:23:54 +0200 |
commit | d2c371927e45c1d4e4f7e4ad331a3f68d67d5469 (patch) | |
tree | a3fc0397eb52caa7f407dca5bf02f4a8f83505b7 | |
parent | 512753f8247b927b62fd9391ee5ba6dda29ea4d4 (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.
-rw-r--r-- | src/nix/command.hh | 2 | ||||
-rw-r--r-- | src/nix/installables.cc | 12 |
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() |