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.
This commit is contained in:
parent
512753f824
commit
d2c371927e
2 changed files with 10 additions and 4 deletions
|
@ -41,7 +41,7 @@ private:
|
||||||
|
|
||||||
std::shared_ptr<EvalState> evalState;
|
std::shared_ptr<EvalState> evalState;
|
||||||
|
|
||||||
Value * vSourceExpr = 0;
|
std::shared_ptr<Value> vSourceExpr;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RealiseMode { Build, NoBuild, DryRun };
|
enum RealiseMode { Build, NoBuild, DryRun };
|
||||||
|
|
|
@ -8,10 +8,13 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
|
|
||||||
|
#include <gc/gc.h>
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
SourceExprCommand::SourceExprCommand()
|
SourceExprCommand::SourceExprCommand()
|
||||||
{
|
{
|
||||||
mkFlag()
|
mkFlag()
|
||||||
|
@ -24,11 +27,14 @@ SourceExprCommand::SourceExprCommand()
|
||||||
|
|
||||||
Value * SourceExprCommand::getSourceExpr(EvalState & state)
|
Value * SourceExprCommand::getSourceExpr(EvalState & state)
|
||||||
{
|
{
|
||||||
if (vSourceExpr) return vSourceExpr;
|
if (vSourceExpr) return vSourceExpr.get();
|
||||||
|
|
||||||
auto sToplevel = state.symbols.create("_toplevel");
|
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 != "")
|
if (file != "")
|
||||||
state.evalFile(lookupFileArg(state, file), *vSourceExpr);
|
state.evalFile(lookupFileArg(state, file), *vSourceExpr);
|
||||||
|
@ -69,7 +75,7 @@ Value * SourceExprCommand::getSourceExpr(EvalState & state)
|
||||||
vSourceExpr->attrs->sort();
|
vSourceExpr->attrs->sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return vSourceExpr;
|
return vSourceExpr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<EvalState> SourceExprCommand::getEvalState()
|
ref<EvalState> SourceExprCommand::getEvalState()
|
||||||
|
|
Loading…
Reference in a new issue