* When allocating an attribute set, reserve enough space for all
elements. This prevents the vector from having to resize itself.
This commit is contained in:
parent
e0b7fb8f27
commit
43535499f3
4 changed files with 21 additions and 28 deletions
|
@ -340,11 +340,12 @@ void EvalState::mkList(Value & v, unsigned int length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::mkAttrs(Value & v)
|
void EvalState::mkAttrs(Value & v, unsigned int expected)
|
||||||
{
|
{
|
||||||
clearValue(v);
|
clearValue(v);
|
||||||
v.type = tAttrs;
|
v.type = tAttrs;
|
||||||
v.attrs = NEW Bindings;
|
v.attrs = NEW Bindings;
|
||||||
|
v.attrs->reserve(expected);
|
||||||
nrAttrsets++;
|
nrAttrsets++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,13 +392,6 @@ Value * EvalState::maybeThunk(Env & env, Expr * expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::cloneAttrs(Value & src, Value & dst)
|
|
||||||
{
|
|
||||||
mkAttrs(dst);
|
|
||||||
*dst.attrs = *src.attrs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EvalState::evalFile(const Path & path, Value & v)
|
void EvalState::evalFile(const Path & path, Value & v)
|
||||||
{
|
{
|
||||||
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
|
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
|
||||||
|
@ -504,7 +498,7 @@ void ExprPath::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
state.mkAttrs(v); // !!! reserve size
|
state.mkAttrs(v, attrs.size());
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
/* Create a new environment that contains the attributes in
|
/* Create a new environment that contains the attributes in
|
||||||
|
@ -758,7 +752,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
||||||
}
|
}
|
||||||
|
|
||||||
Value actualArgs;
|
Value actualArgs;
|
||||||
mkAttrs(actualArgs);
|
mkAttrs(actualArgs, fun.lambda.fun->formals->formals.size());
|
||||||
|
|
||||||
foreach (Formals::Formals_::iterator, i, fun.lambda.fun->formals->formals) {
|
foreach (Formals::Formals_::iterator, i, fun.lambda.fun->formals->formals) {
|
||||||
Bindings::iterator j = args.find(i->name);
|
Bindings::iterator j = args.find(i->name);
|
||||||
|
@ -852,7 +846,7 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
||||||
if (v1.attrs->size() == 0) { v = v2; return; }
|
if (v1.attrs->size() == 0) { v = v2; return; }
|
||||||
if (v2.attrs->size() == 0) { v = v1; return; }
|
if (v2.attrs->size() == 0) { v = v1; return; }
|
||||||
|
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v, v1.attrs->size() + v2.attrs->size());
|
||||||
|
|
||||||
/* Merge the attribute sets, preferring values from the second
|
/* Merge the attribute sets, preferring values from the second
|
||||||
set. Make sure to keep the resulting vector in sorted
|
set. Make sure to keep the resulting vector in sorted
|
||||||
|
|
|
@ -319,13 +319,11 @@ public:
|
||||||
Value * allocAttr(Value & vAttrs, const Symbol & name);
|
Value * allocAttr(Value & vAttrs, const Symbol & name);
|
||||||
|
|
||||||
void mkList(Value & v, unsigned int length);
|
void mkList(Value & v, unsigned int length);
|
||||||
void mkAttrs(Value & v);
|
void mkAttrs(Value & v, unsigned int expected);
|
||||||
void mkThunk_(Value & v, Expr * expr);
|
void mkThunk_(Value & v, Expr * expr);
|
||||||
|
|
||||||
Value * maybeThunk(Env & env, Expr * expr);
|
Value * maybeThunk(Env & env, Expr * expr);
|
||||||
|
|
||||||
void cloneAttrs(Value & src, Value & dst);
|
|
||||||
|
|
||||||
/* Print statistics. */
|
/* Print statistics. */
|
||||||
void printStats();
|
void printStats();
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ static void prim_addErrorContext(EvalState & state, Value * * args, Value & v)
|
||||||
* else => {success=false; value=false;} */
|
* else => {success=false; value=false;} */
|
||||||
static void prim_tryEval(EvalState & state, Value * * args, Value & v)
|
static void prim_tryEval(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v, 2);
|
||||||
try {
|
try {
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
v.attrs->push_back(Attr(state.symbols.create("value"), args[0]));
|
v.attrs->push_back(Attr(state.symbols.create("value"), args[0]));
|
||||||
|
@ -484,7 +484,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
state.drvHashes[drvPath] = hashDerivationModulo(state, drv);
|
state.drvHashes[drvPath] = hashDerivationModulo(state, drv);
|
||||||
|
|
||||||
/* !!! assumes a single output */
|
/* !!! assumes a single output */
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v, 2);
|
||||||
mkString(*state.allocAttr(v, state.sOutPath), outPath, singleton<PathSet>(drvPath));
|
mkString(*state.allocAttr(v, state.sOutPath), outPath, singleton<PathSet>(drvPath));
|
||||||
mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath));
|
mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath));
|
||||||
v.attrs->sort();
|
v.attrs->sort();
|
||||||
|
@ -745,7 +745,7 @@ static void prim_removeAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
/* Copy all attributes not in that set. Note that we don't need
|
/* Copy all attributes not in that set. Note that we don't need
|
||||||
to sort v.attrs because it's a subset of an already sorted
|
to sort v.attrs because it's a subset of an already sorted
|
||||||
vector. */
|
vector. */
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v, args[0]->attrs->size());
|
||||||
foreach (Bindings::iterator, i, *args[0]->attrs) {
|
foreach (Bindings::iterator, i, *args[0]->attrs) {
|
||||||
if (names.find(i->name) == names.end())
|
if (names.find(i->name) == names.end())
|
||||||
v.attrs->push_back(*i);
|
v.attrs->push_back(*i);
|
||||||
|
@ -761,7 +761,7 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceList(*args[0]);
|
state.forceList(*args[0]);
|
||||||
|
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v, args[0]->list.length);
|
||||||
|
|
||||||
std::set<Symbol> seen;
|
std::set<Symbol> seen;
|
||||||
|
|
||||||
|
@ -798,7 +798,7 @@ static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
state.forceAttrs(*args[0]);
|
state.forceAttrs(*args[0]);
|
||||||
state.forceAttrs(*args[1]);
|
state.forceAttrs(*args[1]);
|
||||||
|
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v, std::min(args[0]->attrs->size(), args[1]->attrs->size()));
|
||||||
|
|
||||||
foreach (Bindings::iterator, i, *args[0]->attrs) {
|
foreach (Bindings::iterator, i, *args[0]->attrs) {
|
||||||
Bindings::iterator j = args[1]->attrs->find(i->name);
|
Bindings::iterator j = args[1]->attrs->find(i->name);
|
||||||
|
@ -827,14 +827,15 @@ static void prim_functionArgs(EvalState & state, Value * * args, Value & v)
|
||||||
if (args[0]->type != tLambda)
|
if (args[0]->type != tLambda)
|
||||||
throw TypeError("`functionArgs' requires a function");
|
throw TypeError("`functionArgs' requires a function");
|
||||||
|
|
||||||
state.mkAttrs(v);
|
if (!args[0]->lambda.fun->matchAttrs) {
|
||||||
|
state.mkAttrs(v, 0);
|
||||||
if (!args[0]->lambda.fun->matchAttrs) return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.mkAttrs(v, args[0]->lambda.fun->formals->formals.size());
|
||||||
foreach (Formals::Formals_::iterator, i, args[0]->lambda.fun->formals->formals)
|
foreach (Formals::Formals_::iterator, i, args[0]->lambda.fun->formals->formals)
|
||||||
// !!! should optimise booleans (allocate only once)
|
// !!! should optimise booleans (allocate only once)
|
||||||
mkBool(*state.allocAttr(v, i->name), i->def);
|
mkBool(*state.allocAttr(v, i->name), i->def);
|
||||||
|
|
||||||
v.attrs->sort();
|
v.attrs->sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,7 +1016,7 @@ static void prim_parseDrvName(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string name = state.forceStringNoCtx(*args[0]);
|
string name = state.forceStringNoCtx(*args[0]);
|
||||||
DrvName parsed(name);
|
DrvName parsed(name);
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v, 2);
|
||||||
mkString(*state.allocAttr(v, state.sName), parsed.name);
|
mkString(*state.allocAttr(v, state.sName), parsed.name);
|
||||||
mkString(*state.allocAttr(v, state.symbols.create("version")), parsed.version);
|
mkString(*state.allocAttr(v, state.symbols.create("version")), parsed.version);
|
||||||
v.attrs->sort();
|
v.attrs->sort();
|
||||||
|
@ -1043,7 +1044,7 @@ void EvalState::createBaseEnv()
|
||||||
Value v;
|
Value v;
|
||||||
|
|
||||||
/* `builtins' must be first! */
|
/* `builtins' must be first! */
|
||||||
mkAttrs(v);
|
mkAttrs(v, 128);
|
||||||
addConstant("builtins", v);
|
addConstant("builtins", v);
|
||||||
|
|
||||||
mkBool(v, true);
|
mkBool(v, true);
|
||||||
|
|
|
@ -61,7 +61,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
|
|
||||||
Value & v(*state.allocValue());
|
Value & v(*state.allocValue());
|
||||||
manifest.list.elems[n++] = &v;
|
manifest.list.elems[n++] = &v;
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v, 8);
|
||||||
|
|
||||||
mkString(*state.allocAttr(v, state.sType), "derivation");
|
mkString(*state.allocAttr(v, state.sType), "derivation");
|
||||||
mkString(*state.allocAttr(v, state.sName), i->name);
|
mkString(*state.allocAttr(v, state.sName), i->name);
|
||||||
|
@ -71,7 +71,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
mkString(*state.allocAttr(v, state.sDrvPath), i->queryDrvPath(state));
|
mkString(*state.allocAttr(v, state.sDrvPath), i->queryDrvPath(state));
|
||||||
|
|
||||||
Value & vMeta = *state.allocAttr(v, state.sMeta);
|
Value & vMeta = *state.allocAttr(v, state.sMeta);
|
||||||
state.mkAttrs(vMeta);
|
state.mkAttrs(vMeta, 16);
|
||||||
|
|
||||||
MetaInfo meta = i->queryMetaInfo(state);
|
MetaInfo meta = i->queryMetaInfo(state);
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
/* Construct a Nix expression that calls the user environment
|
/* Construct a Nix expression that calls the user environment
|
||||||
builder with the manifest as argument. */
|
builder with the manifest as argument. */
|
||||||
Value args, topLevel;
|
Value args, topLevel;
|
||||||
state.mkAttrs(args);
|
state.mkAttrs(args, 3);
|
||||||
mkString(*state.allocAttr(args, state.sSystem), thisSystem);
|
mkString(*state.allocAttr(args, state.sSystem), thisSystem);
|
||||||
mkString(*state.allocAttr(args, state.symbols.create("manifest")),
|
mkString(*state.allocAttr(args, state.symbols.create("manifest")),
|
||||||
manifestFile, singleton<PathSet>(manifestFile));
|
manifestFile, singleton<PathSet>(manifestFile));
|
||||||
|
|
Loading…
Reference in a new issue