Author: eelco
Date: Fri Oct 22 14:47:42 2010
New Revision: 24420
URL: https://svn.nixos.org/websvn/nix/?rev=24420&sc=1
Log:
* Store Value nodes outside of attribute sets. I.e., Attr now stores
a pointer to a Value, rather than the Value directly. This improves
the effectiveness of garbage collection a lot: if the Value is
stored inside the set directly, then any live pointer to the Value
causes all other attributes in the set to be live as well.
Modified:
nix/branches/gc/src/libexpr/Makefile.am
nix/branches/gc/src/libexpr/attr-path.cc
nix/branches/gc/src/libexpr/attr-path.hh
nix/branches/gc/src/libexpr/common-opts.cc
nix/branches/gc/src/libexpr/eval.cc
nix/branches/gc/src/libexpr/eval.hh
nix/branches/gc/src/libexpr/get-drvs.cc
nix/branches/gc/src/libexpr/get-drvs.hh
nix/branches/gc/src/libexpr/nixexpr.cc
nix/branches/gc/src/libexpr/nixexpr.hh
nix/branches/gc/src/libexpr/primops.cc
nix/branches/gc/src/libexpr/value-to-xml.cc
nix/branches/gc/src/nix-env/nix-env.cc
nix/branches/gc/src/nix-env/user-env.cc
nix/branches/gc/src/nix-instantiate/nix-instantiate.cc
Modified: nix/branches/gc/src/libexpr/Makefile.am
==============================================================================
--- nix/branches/gc/src/libexpr/Makefile.am Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/Makefile.am Fri Oct 22 14:47:42 2010
(r24420)
@@ -11,7 +11,7 @@
names.hh symbol-table.hh
libexpr_la_LIBADD = ../libutil/libutil.la ../libstore/libstore.la \
- ../boost/format/libformat.la
+ ../boost/format/libformat.la @boehmgc_lib@
BUILT_SOURCES = \
parser-tab.hh lexer-tab.hh parser-tab.cc lexer-tab.cc
Modified: nix/branches/gc/src/libexpr/attr-path.cc
==============================================================================
--- nix/branches/gc/src/libexpr/attr-path.cc Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/attr-path.cc Fri Oct 22 14:47:42 2010
(r24420)
@@ -5,8 +5,9 @@
namespace nix {
+// !!! Shouldn't we return a pointer to a Value?
void findAlongAttrPath(EvalState & state, const string & attrPath,
- const Bindings & autoArgs, Expr * e, Value & v)
+ Bindings & autoArgs, Expr * e, Value & v)
{
Strings tokens = tokenizeString(attrPath, ".");
@@ -48,7 +49,7 @@
Bindings::iterator a = v.attrs->find(state.symbols.create(attr));
if (a == v.attrs->end())
throw Error(format("attribute `%1%' in selection path `%2%'
not found") % attr % curPath);
- v = a->second.value;
+ v = *a->second.value;
}
else if (apType == apIndex) {
Modified: nix/branches/gc/src/libexpr/attr-path.hh
==============================================================================
--- nix/branches/gc/src/libexpr/attr-path.hh Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/attr-path.hh Fri Oct 22 14:47:42 2010
(r24420)
@@ -11,7 +11,7 @@
void findAlongAttrPath(EvalState & state, const string & attrPath,
- const Bindings & autoArgs, Expr * e, Value & v);
+ Bindings & autoArgs, Expr * e, Value & v);
}
Modified: nix/branches/gc/src/libexpr/common-opts.cc
==============================================================================
--- nix/branches/gc/src/libexpr/common-opts.cc Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/common-opts.cc Fri Oct 22 14:47:42 2010
(r24420)
@@ -20,12 +20,13 @@
if (i == argsEnd) throw error;
string value = *i++;
- Value & v(autoArgs[state.symbols.create(name)].value);
+ Value * v = state.allocValue();
+ autoArgs[state.symbols.create(name)].value = v;
if (arg == "--arg")
- state.mkThunk_(v, parseExprFromString(state, value, absPath(".")));
+ state.mkThunk_(*v, parseExprFromString(state, value, absPath(".")));
else
- mkString(v, value);
+ mkString(*v, value);
return true;
}
Modified: nix/branches/gc/src/libexpr/eval.cc
==============================================================================
--- nix/branches/gc/src/libexpr/eval.cc Fri Oct 22 14:40:19 2010 (r24419)
+++ nix/branches/gc/src/libexpr/eval.cc Fri Oct 22 14:47:42 2010 (r24420)
@@ -58,7 +58,7 @@
typedef std::map<string, Value *> Sorted;
Sorted sorted;
foreach (Bindings::iterator, i, *v.attrs)
- sorted[i->first] = &i->second.value;
+ sorted[i->first] = i->second.value;
foreach (Sorted::iterator, i, sorted)
str << i->first << " = " << *i->second << "; ";
str << "}";
@@ -145,24 +145,26 @@
void EvalState::addConstant(const string & name, Value & v)
{
+ Value * v2 = allocValue();
+ *v2 = v;
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
baseEnv.values[baseEnvDispl++] = v;
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
- (*baseEnv.values[0].attrs)[symbols.create(name2)].value = v;
+ (*baseEnv.values[0].attrs)[symbols.create(name2)].value = v2;
}
void EvalState::addPrimOp(const string & name,
unsigned int arity, PrimOp primOp)
{
- Value v;
+ Value * v = allocValue();
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
- v.type = tPrimOp;
- v.primOp.arity = arity;
- v.primOp.fun = primOp;
- v.primOp.name = GC_STRDUP(name2.c_str());
+ v->type = tPrimOp;
+ v->primOp.arity = arity;
+ v->primOp.fun = primOp;
+ v->primOp.name = GC_STRDUP(name2.c_str());
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
- baseEnv.values[baseEnvDispl++] = v;
+ baseEnv.values[baseEnvDispl++] = *v;
(*baseEnv.values[0].attrs)[symbols.create(name2)].value = v;
}
@@ -265,7 +267,7 @@
while (1) {
Bindings::iterator j = env->values[0].attrs->find(var.name);
if (j != env->values[0].attrs->end())
- return &j->second.value;
+ return j->second.value;
if (env->prevWith == 0)
throwEvalError("undefined variable `%1%'", var.name);
for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
@@ -275,6 +277,13 @@
}
+Value * EvalState::allocValue()
+{
+ nrValues++;
+ return (Value *) GC_MALLOC(sizeof(Value));
+}
+
+
Value * EvalState::allocValues(unsigned int count)
{
nrValues += count;
@@ -291,6 +300,14 @@
}
+Value * EvalState::allocAttr(Value & vAttrs, const Symbol & name)
+{
+ Attr & a = (*vAttrs.attrs)[name];
+ a.value = allocValue();
+ return a.value;
+}
+
+
void EvalState::mkList(Value & v, unsigned int length)
{
v.type = tList;
@@ -321,11 +338,8 @@
void EvalState::cloneAttrs(Value & src, Value & dst)
{
mkAttrs(dst);
- foreach (Bindings::iterator, i, *src.attrs) {
- Attr & a = (*dst.attrs)[i->first];
- mkCopy(a.value, i->second.value);
- a.pos = i->second.pos;
- }
+ foreach (Bindings::iterator, i, *src.attrs)
+ (*dst.attrs)[i->first] = i->second;
}
@@ -449,8 +463,9 @@
environment. */
foreach (Attrs::iterator, i, attrs) {
nix::Attr & a = (*v.attrs)[i->first];
- mkThunk(a.value, env2, i->second.first);
- mkCopy(env2.values[displ++], a.value);
+ a.value = state.allocValue();
+ mkThunk(*a.value, env2, i->second.first);
+ mkCopy(env2.values[displ++], *a.value);
a.pos = &i->second.second;
}
@@ -459,7 +474,7 @@
foreach (list<Inherited>::iterator, i, inherited) {
nix::Attr & a = (*v.attrs)[i->first.name];
Value * v2 = state.lookupVar(&env, i->first);
- mkCopy(a.value, *v2);
+ a.value = v2;
mkCopy(env2.values[displ++], *v2);
a.pos = &i->second;
}
@@ -474,10 +489,12 @@
Hence we need __overrides.) */
Bindings::iterator overrides = v.attrs->find(state.sOverrides);
if (overrides != v.attrs->end()) {
- state.forceAttrs(overrides->second.value);
- foreach (Bindings::iterator, i, *overrides->second.value.attrs) {
+ state.forceAttrs(*overrides->second.value);
+ foreach (Bindings::iterator, i, *overrides->second.value->attrs) {
nix::Attr & a = (*v.attrs)[i->first];
- mkCopy(a.value, i->second.value);
+ if (a.value)
+ mkCopy(env2.values[displs[i->first]], *i->second.value);
+ a = i->second;
}
}
}
@@ -485,13 +502,14 @@
else {
foreach (Attrs::iterator, i, attrs) {
nix::Attr & a = (*v.attrs)[i->first];
- mkThunk(a.value, env, i->second.first);
+ a.value = state.allocValue();
+ mkThunk(*a.value, env, i->second.first);
a.pos = &i->second.second;
}
foreach (list<Inherited>::iterator, i, inherited) {
nix::Attr & a = (*v.attrs)[i->first.name];
- mkCopy(a.value, *state.lookupVar(&env, i->first));
+ a.value = state.lookupVar(&env, i->first);
a.pos = &i->second;
}
}
@@ -548,13 +566,13 @@
if (i == v2.attrs->end())
throwEvalError("attribute `%1%' missing", name);
try {
- state.forceValue(i->second.value);
+ state.forceValue(*i->second.value);
} catch (Error & e) {
addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
name, *i->second.pos);
throw;
}
- v = i->second.value;
+ v = *i->second.value;
}
@@ -578,9 +596,9 @@
{
Value vFun;
state.eval(env, e1, vFun);
- Value vArg;
- mkThunk(vArg, env, e2); // !!! should this be on the heap?
- state.callFunction(vFun, vArg, v);
+ Value * vArg = state.allocValue();
+ mkThunk(*vArg, env, e2);
+ state.callFunction(vFun, *vArg, v);
}
@@ -656,7 +674,7 @@
mkThunk(env2.values[displ++], env2, i->def);
} else {
attrsUsed++;
- mkCopy(env2.values[displ++], j->second.value);
+ mkCopy(env2.values[displ++], *j->second.value);
}
}
@@ -677,7 +695,7 @@
}
-void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value &
res)
+void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
{
forceValue(fun);
@@ -690,7 +708,7 @@
mkAttrs(actualArgs);
foreach (Formals::Formals_::iterator, i, fun.lambda.fun->formals->formals)
{
- Bindings::const_iterator j = args.find(i->name);
+ Bindings::iterator j = args.find(i->name);
if (j != args.end())
(*actualArgs.attrs)[i->name] = j->second;
else if (!i->def)
@@ -780,11 +798,8 @@
state.cloneAttrs(v1, v);
- foreach (Bindings::iterator, i, *v2.attrs) {
- Attr & a = (*v.attrs)[i->first];
- mkCopy(a.value, i->second.value);
- a.pos = i->second.pos;
- }
+ foreach (Bindings::iterator, i, *v2.attrs)
+ (*v.attrs)[i->first] = i->second;
state.nrOpUpdateValuesCopied += v.attrs->size();
}
@@ -866,7 +881,7 @@
if (v.type == tAttrs) {
foreach (Bindings::iterator, i, *v.attrs)
- strictForceValue(i->second.value);
+ strictForceValue(*i->second.value);
}
else if (v.type == tList) {
@@ -957,7 +972,7 @@
{
if (v.type != tAttrs) return false;
Bindings::iterator i = v.attrs->find(sType);
- return i != v.attrs->end() && forceStringNoCtx(i->second.value) ==
"derivation";
+ return i != v.attrs->end() && forceStringNoCtx(*i->second.value) ==
"derivation";
}
@@ -1001,7 +1016,7 @@
Bindings::iterator i = v.attrs->find(sOutPath);
if (i == v.attrs->end())
throwTypeError("cannot coerce an attribute set (except a
derivation) to a string");
- return coerceToString(i->second.value, context, coerceMore,
copyToStore);
+ return coerceToString(*i->second.value, context, coerceMore,
copyToStore);
}
if (coerceMore) {
@@ -1087,9 +1102,9 @@
case tAttrs: {
if (v1.attrs->size() != v2.attrs->size()) return false;
- Bindings::iterator i, j;
- for (i = v1.attrs->begin(), j = v2.attrs->begin(); i !=
v1.attrs->end(); ++i, ++j)
- if (i->first != j->first || !eqValues(i->second.value,
j->second.value))
+ Bindings::iterator i = v1.attrs->begin(), j = v2.attrs->begin();
+ for ( ; i != v1.attrs->end(); ++i, ++j)
+ if (i->first != j->first || !eqValues(*i->second.value,
*j->second.value))
return false;
return true;
}
Modified: nix/branches/gc/src/libexpr/eval.hh
==============================================================================
--- nix/branches/gc/src/libexpr/eval.hh Fri Oct 22 14:40:19 2010 (r24419)
+++ nix/branches/gc/src/libexpr/eval.hh Fri Oct 22 14:47:42 2010 (r24420)
@@ -122,7 +122,7 @@
struct Attr
{
- Value value;
+ Value * value;
Pos * pos;
Attr() : pos(&noPos) { };
};
@@ -294,12 +294,15 @@
/* Automatically call a function for which each argument has a
default value or has a binding in the `args' map. */
- void autoCallFunction(const Bindings & args, Value & fun, Value & res);
+ void autoCallFunction(Bindings & args, Value & fun, Value & res);
/* Allocation primitives. */
+ Value * allocValue();
Value * allocValues(unsigned int count);
Env & allocEnv(unsigned int size);
+ Value * allocAttr(Value & vAttrs, const Symbol & name);
+
void mkList(Value & v, unsigned int length);
void mkAttrs(Value & v);
void mkThunk_(Value & v, Expr * expr);
Modified: nix/branches/gc/src/libexpr/get-drvs.cc
==============================================================================
--- nix/branches/gc/src/libexpr/get-drvs.cc Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/get-drvs.cc Fri Oct 22 14:47:42 2010
(r24420)
@@ -10,7 +10,7 @@
if (drvPath == "" && attrs) {
Bindings::iterator i = attrs->find(state.sDrvPath);
PathSet context;
- (string &) drvPath = i != attrs->end() ?
state.coerceToPath(i->second.value, context) : "";
+ (string &) drvPath = i != attrs->end() ?
state.coerceToPath(*i->second.value, context) : "";
}
return drvPath;
}
@@ -21,7 +21,7 @@
if (outPath == "" && attrs) {
Bindings::iterator i = attrs->find(state.sOutPath);
PathSet context;
- (string &) outPath = i != attrs->end() ?
state.coerceToPath(i->second.value, context) : "";
+ (string &) outPath = i != attrs->end() ?
state.coerceToPath(*i->second.value, context) : "";
}
return outPath;
}
@@ -36,21 +36,21 @@
Bindings::iterator a = attrs->find(state.sMeta);
if (a == attrs->end()) return meta; /* fine, empty meta information */
- state.forceAttrs(a->second.value);
+ state.forceAttrs(*a->second.value);
- foreach (Bindings::iterator, i, *a->second.value.attrs) {
+ foreach (Bindings::iterator, i, *a->second.value->attrs) {
MetaValue value;
- state.forceValue(i->second.value);
- if (i->second.value.type == tString) {
+ state.forceValue(*i->second.value);
+ if (i->second.value->type == tString) {
value.type = MetaValue::tpString;
- value.stringValue = i->second.value.string.s;
- } else if (i->second.value.type == tInt) {
+ value.stringValue = i->second.value->string.s;
+ } else if (i->second.value->type == tInt) {
value.type = MetaValue::tpInt;
- value.intValue = i->second.value.integer;
- } else if (i->second.value.type == tList) {
+ value.intValue = i->second.value->integer;
+ } else if (i->second.value->type == tList) {
value.type = MetaValue::tpStrings;
- for (unsigned int j = 0; j < i->second.value.list.length; ++j)
-
value.stringValues.push_back(state.forceStringNoCtx(*i->second.value.list.elems[j]));
+ for (unsigned int j = 0; j < i->second.value->list.length; ++j)
+
value.stringValues.push_back(state.forceStringNoCtx(*i->second.value->list.elems[j]));
} else continue;
((MetaInfo &) meta)[i->first] = value;
}
@@ -99,13 +99,13 @@
Bindings::iterator i = v.attrs->find(state.sName);
/* !!! We really would like to have a decent back trace here. */
if (i == v.attrs->end()) throw TypeError("derivation name missing");
- drv.name = state.forceStringNoCtx(i->second.value);
+ drv.name = state.forceStringNoCtx(*i->second.value);
- i = v.attrs->find(state.sSystem);
- if (i == v.attrs->end())
+ Bindings::iterator i2 = v.attrs->find(state.sSystem);
+ if (i2 == v.attrs->end())
drv.system = "unknown";
else
- drv.system = state.forceStringNoCtx(i->second.value);
+ drv.system = state.forceStringNoCtx(*i2->second.value);
drv.attrs = v.attrs;
@@ -138,7 +138,7 @@
static void getDerivations(EvalState & state, Value & vIn,
- const string & pathPrefix, const Bindings & autoArgs,
+ const string & pathPrefix, Bindings & autoArgs,
DrvInfos & drvs, Done & done)
{
Value v;
@@ -168,7 +168,7 @@
foreach (SortedSymbols::iterator, i, attrs) {
startNest(nest, lvlDebug, format("evaluating attribute `%1%'") %
i->first);
string pathPrefix2 = addToPath(pathPrefix, i->first);
- Value & v2((*v.attrs)[i->second].value);
+ Value & v2(*(*v.attrs)[i->second].value);
if (combineChannels)
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
else if (getDerivation(state, v2, pathPrefix2, drvs, done)) {
@@ -178,7 +178,7 @@
attribute. */
if (v2.type == tAttrs) {
Bindings::iterator j =
v2.attrs->find(state.symbols.create("recurseForDerivations"));
- if (j != v2.attrs->end() &&
state.forceBool(j->second.value))
+ if (j != v2.attrs->end() &&
state.forceBool(*j->second.value))
getDerivations(state, v2, pathPrefix2, autoArgs, drvs,
done);
}
}
@@ -200,7 +200,7 @@
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
- const Bindings & autoArgs, DrvInfos & drvs)
+ Bindings & autoArgs, DrvInfos & drvs)
{
Done done;
getDerivations(state, v, pathPrefix, autoArgs, drvs, done);
Modified: nix/branches/gc/src/libexpr/get-drvs.hh
==============================================================================
--- nix/branches/gc/src/libexpr/get-drvs.hh Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/get-drvs.hh Fri Oct 22 14:47:42 2010
(r24420)
@@ -70,7 +70,7 @@
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv);
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
- const Bindings & autoArgs, DrvInfos & drvs);
+ Bindings & autoArgs, DrvInfos & drvs);
}
Modified: nix/branches/gc/src/libexpr/nixexpr.cc
==============================================================================
--- nix/branches/gc/src/libexpr/nixexpr.cc Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/nixexpr.cc Fri Oct 22 14:47:42 2010
(r24420)
@@ -213,10 +213,10 @@
unsigned int displ = 0;
foreach (ExprAttrs::Attrs::iterator, i, attrs)
- newEnv.vars[i->first] = displ++;
+ displs[i->first] = newEnv.vars[i->first] = displ++;
foreach (list<Inherited>::iterator, i, inherited) {
- newEnv.vars[i->first.name] = displ++;
+ displs[i->first.name] = newEnv.vars[i->first.name] = displ++;
i->first.bind(env);
}
Modified: nix/branches/gc/src/libexpr/nixexpr.hh
==============================================================================
--- nix/branches/gc/src/libexpr/nixexpr.hh Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/nixexpr.hh Fri Oct 22 14:47:42 2010
(r24420)
@@ -137,6 +137,7 @@
Attrs attrs;
list<Inherited> inherited;
std::map<Symbol, Pos> attrNames; // used during parsing
+ std::map<Symbol, unsigned int> displs;
ExprAttrs() : recursive(false) { };
COMMON_METHODS
};
Modified: nix/branches/gc/src/libexpr/primops.cc
==============================================================================
--- nix/branches/gc/src/libexpr/primops.cc Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/primops.cc Fri Oct 22 14:47:42 2010
(r24420)
@@ -119,24 +119,24 @@
args[0]->attrs->find(state.symbols.create("startSet"));
if (startSet == args[0]->attrs->end())
throw EvalError("attribute `startSet' required");
- state.forceList(startSet->second.value);
+ state.forceList(*startSet->second.value);
list<Value *> workSet;
- for (unsigned int n = 0; n < startSet->second.value.list.length; ++n)
- workSet.push_back(startSet->second.value.list.elems[n]);
+ for (unsigned int n = 0; n < startSet->second.value->list.length; ++n)
+ workSet.push_back(startSet->second.value->list.elems[n]);
/* Get the operator. */
Bindings::iterator op =
args[0]->attrs->find(state.symbols.create("operator"));
if (op == args[0]->attrs->end())
throw EvalError("attribute `operator' required");
- state.forceValue(op->second.value);
+ state.forceValue(*op->second.value);
/* Construct the closure by applying the operator to element of
`workSet', adding the result to `workSet', continuing until
no new elements are found. */
list<Value> res;
- set<Value, CompareValues> doneKeys;
+ set<Value, CompareValues> doneKeys; // !!! use Value *?
while (!workSet.empty()) {
Value * e = *(workSet.begin());
workSet.pop_front();
@@ -147,15 +147,15 @@
e->attrs->find(state.symbols.create("key"));
if (key == e->attrs->end())
throw EvalError("attribute `key' required");
- state.forceValue(key->second.value);
+ state.forceValue(*key->second.value);
- if (doneKeys.find(key->second.value) != doneKeys.end()) continue;
- doneKeys.insert(key->second.value);
+ if (doneKeys.find(*key->second.value) != doneKeys.end()) continue;
+ doneKeys.insert(*key->second.value);
res.push_back(*e);
/* Call the `operator' function with `e' as argument. */
Value call;
- mkApp(call, op->second.value, *e);
+ mkApp(call, *op->second.value, *e);
state.forceList(call);
/* Add the values returned by the operator to the work set. */
@@ -213,11 +213,13 @@
state.mkAttrs(v);
try {
state.forceValue(*args[0]);
- (*v.attrs)[state.symbols.create("value")].value = *args[0];
- mkBool((*v.attrs)[state.symbols.create("success")].value, true);
+ printMsg(lvlError, format("%1%") % *args[0]);
+ (*v.attrs)[state.symbols.create("value")].value = args[0];
+ mkBool(*state.allocAttr(v, state.symbols.create("success")), true);
+ printMsg(lvlError, format("%1%") % v);
} catch (AssertionError & e) {
- mkBool((*v.attrs)[state.symbols.create("value")].value, false);
- mkBool((*v.attrs)[state.symbols.create("success")].value, false);
+ mkBool(*state.allocAttr(v, state.symbols.create("value")), false);
+ mkBool(*state.allocAttr(v, state.symbols.create("success")), false);
}
}
@@ -326,7 +328,7 @@
string drvName;
Pos & posDrvName(*attr->second.pos);
try {
- drvName = state.forceStringNoCtx(attr->second.value);
+ drvName = state.forceStringNoCtx(*attr->second.value);
} catch (Error & e) {
e.addPrefix(format("while evaluating the derivation attribute `name'
at %1%:\n") % posDrvName);
throw;
@@ -349,9 +351,9 @@
/* The `args' attribute is special: it supplies the
command-line arguments to the builder. */
if (key == "args") {
- state.forceList(i->second.value);
- for (unsigned int n = 0; n < i->second.value.list.length; ++n)
{
- string s =
state.coerceToString(*i->second.value.list.elems[n], context, true);
+ state.forceList(*i->second.value);
+ for (unsigned int n = 0; n < i->second.value->list.length;
++n) {
+ string s =
state.coerceToString(*i->second.value->list.elems[n], context, true);
drv.args.push_back(s);
}
}
@@ -359,7 +361,7 @@
/* All other attributes are passed to the builder through
the environment. */
else {
- string s = state.coerceToString(i->second.value, context,
true);
+ string s = state.coerceToString(*i->second.value, context,
true);
drv.env[key] = s;
if (key == "builder") drv.builder = s;
else if (i->first == state.sSystem) drv.platform = s;
@@ -488,8 +490,8 @@
/* !!! assumes a single output */
state.mkAttrs(v);
- mkString((*v.attrs)[state.sOutPath].value, outPath,
singleton<PathSet>(drvPath));
- mkString((*v.attrs)[state.sDrvPath].value, drvPath, singleton<PathSet>("="
+ drvPath));
+ mkString(*state.allocAttr(v, state.sOutPath), outPath,
singleton<PathSet>(drvPath));
+ mkString(*state.allocAttr(v, state.sDrvPath), drvPath,
singleton<PathSet>("=" + drvPath));
}
@@ -713,8 +715,8 @@
if (i == args[1]->attrs->end())
throw EvalError(format("attribute `%1%' missing") % attr);
// !!! add to stack trace?
- state.forceValue(i->second.value);
- v = i->second.value;
+ state.forceValue(*i->second.value);
+ v = *i->second.value;
}
@@ -766,15 +768,13 @@
Bindings::iterator j = v2.attrs->find(state.sName);
if (j == v2.attrs->end())
throw TypeError("`name' attribute missing in a call to
`listToAttrs'");
- string name = state.forceStringNoCtx(j->second.value);
+ string name = state.forceStringNoCtx(*j->second.value);
- j = v2.attrs->find(state.symbols.create("value"));
- if (j == v2.attrs->end())
+ Bindings::iterator j2 = v2.attrs->find(state.symbols.create("value"));
+ if (j2 == v2.attrs->end())
throw TypeError("`value' attribute missing in a call to
`listToAttrs'");
- Attr & a = (*v.attrs)[state.symbols.create(name)];
- mkCopy(a.value, j->second.value);
- a.pos = j->second.pos;
+ (*v.attrs)[state.symbols.create(name)] = j2->second;
}
}
@@ -791,11 +791,8 @@
foreach (Bindings::iterator, i, *args[0]->attrs) {
Bindings::iterator j = args[1]->attrs->find(i->first);
- if (j != args[1]->attrs->end()) {
- Attr & a = (*v.attrs)[j->first];
- mkCopy(a.value, j->second.value);
- a.pos = j->second.pos;
- }
+ if (j != args[1]->attrs->end())
+ (*v.attrs)[j->first] = j->second;
}
}
@@ -824,7 +821,8 @@
if (!args[0]->lambda.fun->matchAttrs) return;
foreach (Formals::Formals_::iterator, i,
args[0]->lambda.fun->formals->formals)
- mkBool((*v.attrs)[i->name].value, i->def);
+ // !!! should optimise booleans (allocate only once)
+ mkBool(*state.allocAttr(v, i->name), i->def);
}
@@ -1007,8 +1005,8 @@
string name = state.forceStringNoCtx(*args[0]);
DrvName parsed(name);
state.mkAttrs(v);
- mkString((*v.attrs)[state.sName].value, parsed.name);
- mkString((*v.attrs)[state.symbols.create("version")].value,
parsed.version);
+ mkString(*state.allocAttr(v, state.sName), parsed.name);
+ mkString(*state.allocAttr(v, state.symbols.create("version")),
parsed.version);
}
Modified: nix/branches/gc/src/libexpr/value-to-xml.cc
==============================================================================
--- nix/branches/gc/src/libexpr/value-to-xml.cc Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/libexpr/value-to-xml.cc Fri Oct 22 14:47:42 2010
(r24420)
@@ -45,7 +45,7 @@
XMLOpenElement _(doc, "attr", xmlAttrs);
printValueAsXML(state, strict, location,
- a.value, doc, context, drvsSeen);
+ *a.value, doc, context, drvsSeen);
}
}
@@ -90,16 +90,16 @@
Path drvPath;
a = v.attrs->find(state.sDrvPath);
if (a != v.attrs->end()) {
- if (strict) state.forceValue(a->second.value);
- if (a->second.value.type == tString)
- xmlAttrs["drvPath"] = drvPath =
a->second.value.string.s;
+ if (strict) state.forceValue(*a->second.value);
+ if (a->second.value->type == tString)
+ xmlAttrs["drvPath"] = drvPath =
a->second.value->string.s;
}
a = v.attrs->find(state.sOutPath);
if (a != v.attrs->end()) {
- if (strict) state.forceValue(a->second.value);
- if (a->second.value.type == tString)
- xmlAttrs["outPath"] = a->second.value.string.s;
+ if (strict) state.forceValue(*a->second.value);
+ if (a->second.value->type == tString)
+ xmlAttrs["outPath"] = a->second.value->string.s;
}
XMLOpenElement _(doc, "derivation", xmlAttrs);
Modified: nix/branches/gc/src/nix-env/nix-env.cc
==============================================================================
--- nix/branches/gc/src/nix-env/nix-env.cc Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/nix-env/nix-env.cc Fri Oct 22 14:47:42 2010
(r24420)
@@ -161,7 +161,7 @@
static void loadDerivations(EvalState & state, Path nixExprPath,
- string systemFilter, const Bindings & autoArgs,
+ string systemFilter, Bindings & autoArgs,
const string & pathPrefix, DrvInfos & elems)
{
Value v;
@@ -321,7 +321,7 @@
static void queryInstSources(EvalState & state,
- const InstallSourceInfo & instSource, const Strings & args,
+ InstallSourceInfo & instSource, const Strings & args,
DrvInfos & elems, bool newestOnly)
{
InstallSourceType type = instSource.type;
Modified: nix/branches/gc/src/nix-env/user-env.cc
==============================================================================
--- nix/branches/gc/src/nix-env/user-env.cc Fri Oct 22 14:40:19 2010
(r24419)
+++ nix/branches/gc/src/nix-env/user-env.cc Fri Oct 22 14:47:42 2010
(r24420)
@@ -25,7 +25,8 @@
if (pathExists(manifestFile)) {
Value v;
state.eval(parseExprFromFile(state, manifestFile), v);
- getDerivations(state, v, "", Bindings(), elems);
+ Bindings bindings;
+ getDerivations(state, v, "", bindings, elems);
} else if (pathExists(oldManifestFile))
readLegacyManifest(oldManifestFile, elems);
@@ -62,19 +63,19 @@
manifest.list.elems[n++] = &v;
state.mkAttrs(v);
- mkString((*v.attrs)[state.sType].value, "derivation");
- mkString((*v.attrs)[state.sName].value, i->name);
- mkString((*v.attrs)[state.sSystem].value, i->system);
- mkString((*v.attrs)[state.sOutPath].value, i->queryOutPath(state));
+ mkString(*state.allocAttr(v, state.sType), "derivation");
+ mkString(*state.allocAttr(v, state.sName), i->name);
+ mkString(*state.allocAttr(v, state.sSystem), i->system);
+ mkString(*state.allocAttr(v, state.sOutPath), i->queryOutPath(state));
if (drvPath != "")
- mkString((*v.attrs)[state.sDrvPath].value, i->queryDrvPath(state));
+ mkString(*state.allocAttr(v, state.sDrvPath),
i->queryDrvPath(state));
- state.mkAttrs((*v.attrs)[state.sMeta].value);
+ state.mkAttrs(*state.allocAttr(v, state.sMeta));
MetaInfo meta = i->queryMetaInfo(state);
foreach (MetaInfo::const_iterator, j, meta) {
- Value &
v2((*(*v.attrs)[state.sMeta].value.attrs)[state.symbols.create(j->first)].value);
+ Value & v2(*state.allocAttr(*(*v.attrs)[state.sMeta].value,
state.symbols.create(j->first)));
switch (j->second.type) {
case MetaValue::tpInt: mkInt(v2, j->second.intValue); break;
case MetaValue::tpString: mkString(v2, j->second.stringValue);
break;
@@ -114,10 +115,10 @@
builder with the manifest as argument. */
Value args, topLevel;
state.mkAttrs(args);
- mkString((*args.attrs)[state.sSystem].value, thisSystem);
- mkString((*args.attrs)[state.symbols.create("manifest")].value,
+ mkString(*state.allocAttr(args, state.sSystem), thisSystem);
+ mkString(*state.allocAttr(args, state.symbols.create("manifest")),
manifestFile, singleton<PathSet>(manifestFile));
- (*args.attrs)[state.symbols.create("derivations")].value = manifest;
+ (*args.attrs)[state.symbols.create("derivations")].value = &manifest;
mkApp(topLevel, envBuilder, args);
/* Evaluate it. */
Modified: nix/branches/gc/src/nix-instantiate/nix-instantiate.cc
==============================================================================
--- nix/branches/gc/src/nix-instantiate/nix-instantiate.cc Fri Oct 22
14:40:19 2010 (r24419)
+++ nix/branches/gc/src/nix-instantiate/nix-instantiate.cc Fri Oct 22
14:47:42 2010 (r24420)
@@ -38,7 +38,7 @@
void processExpr(EvalState & state, const Strings & attrPaths,
- bool parseOnly, bool strict, const Bindings & autoArgs,
+ bool parseOnly, bool strict, Bindings & autoArgs,
bool evalOnly, bool xmlOutput, bool location, Expr * e)
{
if (parseOnly)
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits