Skip to content

Commit

Permalink
SourceExprCommand: allocate the vSourceExpr via uncollectable memory
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
andir committed Apr 13, 2020
1 parent 512753f commit d2c3719
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/nix/command.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private:

std::shared_ptr<EvalState> evalState;

Value * vSourceExpr = 0;
std::shared_ptr<Value> vSourceExpr;
};

enum RealiseMode { Build, NoBuild, DryRun };
Expand Down
12 changes: 9 additions & 3 deletions src/nix/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
#include "store-api.hh"
#include "shared.hh"

#include <gc/gc.h>

#include <regex>

namespace nix {


SourceExprCommand::SourceExprCommand()
{
mkFlag()
Expand All @@ -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);
Expand Down Expand Up @@ -69,7 +75,7 @@ Value * SourceExprCommand::getSourceExpr(EvalState & state)
vSourceExpr->attrs->sort();
}

return vSourceExpr;
return vSourceExpr.get();
}

ref<EvalState> SourceExprCommand::getEvalState()
Expand Down

0 comments on commit d2c3719

Please sign in to comment.