* 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue