* Improve sharing.

This commit is contained in:
Eelco Dolstra 2010-04-01 12:04:57 +00:00
parent 95cc417d76
commit 7b851915bf
3 changed files with 25 additions and 19 deletions

View File

@ -264,7 +264,7 @@ void EvalState::cloneAttrs(Value & src, Value & dst)
{ {
mkAttrs(dst); mkAttrs(dst);
foreach (Bindings::iterator, i, *src.attrs) foreach (Bindings::iterator, i, *src.attrs)
(*dst.attrs)[i->first] = i->second; // !!! sharing? mkCopy((*dst.attrs)[i->first], i->second);
} }
@ -601,8 +601,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
mkThunk(v, env2, def); mkThunk(v, env2, def);
} else { } else {
attrsUsed++; attrsUsed++;
v.type = tCopy; mkCopy(v, j->second);
v.val = &j->second;
} }
} }

View File

@ -112,6 +112,13 @@ static inline void mkThunk(Value & v, Env & env, Expr expr)
} }
static inline void mkCopy(Value & v, Value & src)
{
v.type = tCopy;
v.val = &src;
}
void mkString(Value & v, const char * s); void mkString(Value & v, const char * s);
void mkString(Value & v, const string & s, const PathSet & context = PathSet()); void mkString(Value & v, const string & s, const PathSet & context = PathSet());
void mkPath(Value & v, const char * s); void mkPath(Value & v, const char * s);

View File

@ -91,8 +91,8 @@ void DrvInfo::setMetaInfo(const MetaInfo & meta)
} }
/* Cache for already considered values. */ /* Cache for already considered attrsets. */
typedef set<Value *> Values; typedef set<Bindings *> Done;
/* Evaluate value `v'. If it evaluates to an attribute set of type /* Evaluate value `v'. If it evaluates to an attribute set of type
@ -101,7 +101,7 @@ typedef set<Value *> Values;
makes sense for the caller to recursively search for derivations in makes sense for the caller to recursively search for derivations in
`v'. */ `v'. */
static bool getDerivation(EvalState & state, Value & v, static bool getDerivation(EvalState & state, Value & v,
const string & attrPath, DrvInfos & drvs, Values & doneValues) const string & attrPath, DrvInfos & drvs, Done & done)
{ {
try { try {
state.forceValue(v); state.forceValue(v);
@ -112,8 +112,8 @@ static bool getDerivation(EvalState & state, Value & v,
/* Remove spurious duplicates (e.g., an attribute set like /* Remove spurious duplicates (e.g., an attribute set like
`rec { x = derivation {...}; y = x;}'. */ `rec { x = derivation {...}; y = x;}'. */
if (doneValues.find(&v) != doneValues.end()) return false; if (done.find(v.attrs) != done.end()) return false;
doneValues.insert(&v); done.insert(v.attrs);
DrvInfo drv; DrvInfo drv;
@ -143,9 +143,9 @@ static bool getDerivation(EvalState & state, Value & v,
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv) bool getDerivation(EvalState & state, Value & v, DrvInfo & drv)
{ {
Values doneValues; Done done;
DrvInfos drvs; DrvInfos drvs;
getDerivation(state, v, "", drvs, doneValues); getDerivation(state, v, "", drvs, done);
if (drvs.size() != 1) return false; if (drvs.size() != 1) return false;
drv = drvs.front(); drv = drvs.front();
return true; return true;
@ -160,14 +160,14 @@ static string addToPath(const string & s1, const string & s2)
static void getDerivations(EvalState & state, Value & v, static void getDerivations(EvalState & state, Value & v,
const string & pathPrefix, const ATermMap & autoArgs, const string & pathPrefix, const ATermMap & autoArgs,
DrvInfos & drvs, Values & doneValues) DrvInfos & drvs, Done & done)
{ {
// !!! autoCallFunction(evalExpr(state, e), autoArgs) // !!! autoCallFunction(evalExpr(state, e), autoArgs)
/* Process the expression. */ /* Process the expression. */
DrvInfo drv; DrvInfo drv;
if (!getDerivation(state, v, pathPrefix, drvs, doneValues)) ; if (!getDerivation(state, v, pathPrefix, drvs, done)) ;
else if (v.type == tAttrs) { else if (v.type == tAttrs) {
@ -189,8 +189,8 @@ static void getDerivations(EvalState & state, Value & v,
string pathPrefix2 = addToPath(pathPrefix, *i); string pathPrefix2 = addToPath(pathPrefix, *i);
Value & v2((*v.attrs)[toATerm(*i)]); Value & v2((*v.attrs)[toATerm(*i)]);
if (combineChannels) if (combineChannels)
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, doneValues); getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
else if (getDerivation(state, v2, pathPrefix2, drvs, doneValues)) { else if (getDerivation(state, v2, pathPrefix2, drvs, done)) {
/* If the value of this attribute is itself an /* If the value of this attribute is itself an
attribute set, should we recurse into it? => Only attribute set, should we recurse into it? => Only
if it has a `recurseForDerivations = true' if it has a `recurseForDerivations = true'
@ -198,7 +198,7 @@ static void getDerivations(EvalState & state, Value & v,
if (v2.type == tAttrs) { if (v2.type == tAttrs) {
Bindings::iterator j = v2.attrs->find(toATerm("recurseForDerivations")); Bindings::iterator j = v2.attrs->find(toATerm("recurseForDerivations"));
if (j != v2.attrs->end() && state.forceBool(j->second)) if (j != v2.attrs->end() && state.forceBool(j->second))
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, doneValues); getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
} }
} }
} }
@ -209,8 +209,8 @@ static void getDerivations(EvalState & state, Value & v,
startNest(nest, lvlDebug, startNest(nest, lvlDebug,
format("evaluating list element")); format("evaluating list element"));
string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str()); string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
if (getDerivation(state, v.list.elems[n], pathPrefix2, drvs, doneValues)) if (getDerivation(state, v.list.elems[n], pathPrefix2, drvs, done))
getDerivations(state, v.list.elems[n], pathPrefix2, autoArgs, drvs, doneValues); getDerivations(state, v.list.elems[n], pathPrefix2, autoArgs, drvs, done);
} }
} }
@ -221,8 +221,8 @@ static void getDerivations(EvalState & state, Value & v,
void getDerivations(EvalState & state, Value & v, const string & pathPrefix, void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
const ATermMap & autoArgs, DrvInfos & drvs) const ATermMap & autoArgs, DrvInfos & drvs)
{ {
Values doneValues; Done done;
getDerivations(state, v, pathPrefix, autoArgs, drvs, doneValues); getDerivations(state, v, pathPrefix, autoArgs, drvs, done);
} }