about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-01T12·04+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-01T12·04+0000
commit7b851915bfbad1c561191a037a2924d2b3d2d398 (patch)
tree6505b7773c1117295d2b00a244379f741a20a915
parent95cc417d76f7d374ef63e0b49a2f83e7b9202b0c (diff)
* Improve sharing.
-rw-r--r--src/libexpr/eval.cc5
-rw-r--r--src/libexpr/eval.hh7
-rw-r--r--src/libexpr/get-drvs.cc32
3 files changed, 25 insertions, 19 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 53e57ff089..49aeb00368 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -264,7 +264,7 @@ void EvalState::cloneAttrs(Value & src, Value & dst)
 {
     mkAttrs(dst);
     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);
             } else {
                 attrsUsed++;
-                v.type = tCopy;
-                v.val = &j->second;
+                mkCopy(v, j->second);
             }
         }
 
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 34b658ce13..ae6b2106f4 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -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 string & s, const PathSet & context = PathSet());
 void mkPath(Value & v, const char * s);
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 93f559cacb..f02392bed5 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -91,8 +91,8 @@ void DrvInfo::setMetaInfo(const MetaInfo & meta)
 }
 
 
-/* Cache for already considered values. */
-typedef set<Value *> Values;
+/* Cache for already considered attrsets. */
+typedef set<Bindings *> Done;
 
 
 /* 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
    `v'. */
 static bool getDerivation(EvalState & state, Value & v,
-    const string & attrPath, DrvInfos & drvs, Values & doneValues)
+    const string & attrPath, DrvInfos & drvs, Done & done)
 {
     try {
         state.forceValue(v);
@@ -112,8 +112,8 @@ static bool getDerivation(EvalState & state, Value & v,
 
         /* Remove spurious duplicates (e.g., an attribute set like
            `rec { x = derivation {...}; y = x;}'. */
-        if (doneValues.find(&v) != doneValues.end()) return false;
-        doneValues.insert(&v);
+        if (done.find(v.attrs) != done.end()) return false;
+        done.insert(v.attrs);
 
         DrvInfo drv;
     
@@ -143,9 +143,9 @@ static bool getDerivation(EvalState & state, Value & v,
 
 bool getDerivation(EvalState & state, Value & v, DrvInfo & drv)
 {
-    Values doneValues;
+    Done done;
     DrvInfos drvs;
-    getDerivation(state, v, "", drvs, doneValues);
+    getDerivation(state, v, "", drvs, done);
     if (drvs.size() != 1) return false;
     drv = drvs.front();
     return true;
@@ -160,14 +160,14 @@ static string addToPath(const string & s1, const string & s2)
 
 static void getDerivations(EvalState & state, Value & v,
     const string & pathPrefix, const ATermMap & autoArgs,
-    DrvInfos & drvs, Values & doneValues)
+    DrvInfos & drvs, Done & done)
 {
     // !!! autoCallFunction(evalExpr(state, e), autoArgs)
     
     /* Process the expression. */
     DrvInfo drv;
 
-    if (!getDerivation(state, v, pathPrefix, drvs, doneValues)) ;
+    if (!getDerivation(state, v, pathPrefix, drvs, done)) ;
 
     else if (v.type == tAttrs) {
 
@@ -189,8 +189,8 @@ static void getDerivations(EvalState & state, Value & v,
             string pathPrefix2 = addToPath(pathPrefix, *i);
             Value & v2((*v.attrs)[toATerm(*i)]);
             if (combineChannels)
-                getDerivations(state, v2, pathPrefix2, autoArgs, drvs, doneValues);
-            else if (getDerivation(state, v2, pathPrefix2, drvs, doneValues)) {
+                getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
+            else if (getDerivation(state, v2, pathPrefix2, drvs, done)) {
                 /* If the value of this attribute is itself an
                    attribute set, should we recurse into it?  => Only
                    if it has a `recurseForDerivations = true'
@@ -198,7 +198,7 @@ static void getDerivations(EvalState & state, Value & v,
                 if (v2.type == tAttrs) {
                     Bindings::iterator j = v2.attrs->find(toATerm("recurseForDerivations"));
                     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,
                 format("evaluating list element"));
             string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
-            if (getDerivation(state, v.list.elems[n], pathPrefix2, drvs, doneValues))
-                getDerivations(state, v.list.elems[n], pathPrefix2, autoArgs, drvs, doneValues);
+            if (getDerivation(state, v.list.elems[n], pathPrefix2, drvs, done))
+                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,
     const ATermMap & autoArgs, DrvInfos & drvs)
 {
-    Values doneValues;
-    getDerivations(state, v, pathPrefix, autoArgs, drvs, doneValues);
+    Done done;
+    getDerivations(state, v, pathPrefix, autoArgs, drvs, done);
 }