about summary refs log tree commit diff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-15T00·37+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-15T00·37+0000
commit04c4bd3624b094043ff0f2410c1e376a51f457f7 (patch)
tree0ff3c39628ceeb26af33f2b461d84a13db9aa561 /src/libexpr/primops.cc
parente41b5828db0c154e4a3f0ed6299a987fde5bc03f (diff)
* Store lists as lists of pointers to values rather than as lists of
  values.  This improves sharing and gives another speed up.
  Evaluation of the NixOS system attribute is now almost 7 times
  faster than the old evaluator.

Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc27
1 files changed, 16 insertions, 11 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 0d7459feef..ae17506cee 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -311,7 +311,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
             if (key == "args") {
                 state.forceList(i->second);
                 for (unsigned int n = 0; n < i->second.list.length; ++n) {
-                    string s = state.coerceToString(i->second.list.elems[n], context, true);
+                    string s = state.coerceToString(*i->second.list.elems[n], context, true);
                     drv.args.push_back(s);
                 }
             }
@@ -651,14 +651,17 @@ static void prim_attrNames(EvalState & state, Value * * args, Value & v)
     state.forceAttrs(*args[0]);
 
     state.mkList(v, args[0]->attrs->size());
+    Value * vs = state.allocValues(v.list.length);
 
     StringSet names;
     foreach (Bindings::iterator, i, *args[0]->attrs)
         names.insert(i->first);
 
     unsigned int n = 0;
-    foreach (StringSet::iterator, i, names)
-        mkString(v.list.elems[n++], *i);
+    foreach (StringSet::iterator, i, names) {
+        v.list.elems[n] = &vs[n];
+        mkString(vs[n++], *i);
+    }
 }
 
 
@@ -701,8 +704,8 @@ static void prim_removeAttrs(EvalState & state, Value * * args, Value & v)
     state.cloneAttrs(*args[0], v);
 
     for (unsigned int i = 0; i < args[1]->list.length; ++i) {
-        state.forceStringNoCtx(args[1]->list.elems[i]);
-        v.attrs->erase(state.symbols.create(args[1]->list.elems[i].string.s));
+        state.forceStringNoCtx(*args[1]->list.elems[i]);
+        v.attrs->erase(state.symbols.create(args[1]->list.elems[i]->string.s));
     }
 }
 
@@ -718,7 +721,7 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
     state.mkAttrs(v);
 
     for (unsigned int i = 0; i < args[0]->list.length; ++i) {
-        Value & v2(args[0]->list.elems[i]);
+        Value & v2(*args[0]->list.elems[i]);
         state.forceAttrs(v2);
         
         Bindings::iterator j = v2.attrs->find(state.sName);
@@ -815,8 +818,8 @@ static void prim_head(EvalState & state, Value * * args, Value & v)
     state.forceList(*args[0]);
     if (args[0]->list.length == 0)
         throw Error("`head' called on an empty list");
-    state.forceValue(args[0]->list.elems[0]);
-    v = args[0]->list.elems[0];
+    state.forceValue(*args[0]->list.elems[0]);
+    v = *args[0]->list.elems[0];
 }
 
 
@@ -840,11 +843,13 @@ static void prim_map(EvalState & state, Value * * args, Value & v)
     state.forceList(*args[1]);
 
     state.mkList(v, args[1]->list.length);
+    Value * vs = state.allocValues(v.list.length);
 
     for (unsigned int n = 0; n < v.list.length; ++n) {
-        v.list.elems[n].type = tApp;
-        v.list.elems[n].app.left = args[0];
-        v.list.elems[n].app.right = &args[1]->list.elems[n];
+        v.list.elems[n] = &vs[n];
+        vs[n].type = tApp;
+        vs[n].app.left = args[0];
+        vs[n].app.right = args[1]->list.elems[n];
     }
 }