* Don't use dynamic_cast, it's very slow. "nix-instantiate
/etc/nixos/nixos -A system" spent about 10% of its time in dynamic_cast.
This commit is contained in:
		
							parent
							
								
									adaf64a99b
								
							
						
					
					
						commit
						35f2a6ba82
					
				
					 3 changed files with 23 additions and 24 deletions
				
			
		|  | @ -404,28 +404,27 @@ void EvalState::mkThunk_(Value & v, Expr * expr) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| unsigned long nrAvoided = 0; |  | ||||||
| 
 |  | ||||||
| /* Create a thunk for the delayed computation of the given expression
 | /* Create a thunk for the delayed computation of the given expression
 | ||||||
|    in the given environment.  But if the expression is a variable, |    in the given environment.  But if the expression is a variable, | ||||||
|    then look it up right away.  This significantly reduces the number |    then look it up right away.  This significantly reduces the number | ||||||
|    of thunks allocated. */ |    of thunks allocated. */ | ||||||
| Value * EvalState::maybeThunk(Env & env, Expr * expr) | Value * Expr::maybeThunk(EvalState & state, Env & env) | ||||||
| { | { | ||||||
|     ExprVar * var; |     Value * v = state.allocValue(); | ||||||
|     /* Ignore variables from `withs' because they can throw an
 |     mkThunk(*v, env, this); | ||||||
|        exception. */ |     return v; | ||||||
|     if ((var = dynamic_cast<ExprVar *>(expr))) { | } | ||||||
|         Value * v = lookupVar(&env, var->info); | 
 | ||||||
|  | 
 | ||||||
|  | unsigned long nrAvoided = 0; | ||||||
|  | 
 | ||||||
|  | Value * ExprVar::maybeThunk(EvalState & state, Env & env) | ||||||
|  | { | ||||||
|  |     Value * v = state.lookupVar(&env, info); | ||||||
|     /* The value might not be initialised in the environment yet.
 |     /* The value might not be initialised in the environment yet.
 | ||||||
|        In that case, ignore it. */ |        In that case, ignore it. */ | ||||||
|     if (v) { nrAvoided++; return v; } |     if (v) { nrAvoided++; return v; } | ||||||
|     } |     return Expr::maybeThunk(state, env); | ||||||
| 
 |  | ||||||
|     Value * v = allocValue(); |  | ||||||
|     mkThunk(*v, env, expr); |  | ||||||
| 
 |  | ||||||
|     return v; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -560,7 +559,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) | ||||||
|                     vAttr = state.allocValue(); |                     vAttr = state.allocValue(); | ||||||
|                     mkThunk(*vAttr, env2, i->second.e); |                     mkThunk(*vAttr, env2, i->second.e); | ||||||
|                 } else |                 } else | ||||||
|                     vAttr = state.maybeThunk(env2, i->second.e); |                     vAttr = i->second.e->maybeThunk(state, env2); | ||||||
|                 env2.values[displ++] = vAttr; |                 env2.values[displ++] = vAttr; | ||||||
|                 v.attrs->push_back(Attr(i->first, vAttr, &i->second.pos)); |                 v.attrs->push_back(Attr(i->first, vAttr, &i->second.pos)); | ||||||
|             } |             } | ||||||
|  | @ -593,7 +592,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) | ||||||
|             if (i->second.inherited) |             if (i->second.inherited) | ||||||
|                 v.attrs->push_back(Attr(i->first, state.lookupVar(&env, i->second.var), &i->second.pos)); |                 v.attrs->push_back(Attr(i->first, state.lookupVar(&env, i->second.var), &i->second.pos)); | ||||||
|             else |             else | ||||||
|                 v.attrs->push_back(Attr(i->first, state.maybeThunk(env, i->second.e), &i->second.pos)); |                 v.attrs->push_back(Attr(i->first, i->second.e->maybeThunk(state, env), &i->second.pos)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -613,7 +612,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) | ||||||
|         if (i->second.inherited) |         if (i->second.inherited) | ||||||
|             env2.values[displ++] = state.lookupVar(&env, i->second.var); |             env2.values[displ++] = state.lookupVar(&env, i->second.var); | ||||||
|         else |         else | ||||||
|             env2.values[displ++] = state.maybeThunk(env2, i->second.e); |             env2.values[displ++] = i->second.e->maybeThunk(state, env2); | ||||||
| 
 | 
 | ||||||
|     state.eval(env2, body, v); |     state.eval(env2, body, v); | ||||||
| } | } | ||||||
|  | @ -623,7 +622,7 @@ void ExprList::eval(EvalState & state, Env & env, Value & v) | ||||||
| { | { | ||||||
|     state.mkList(v, elems.size()); |     state.mkList(v, elems.size()); | ||||||
|     for (unsigned int n = 0; n < v.list.length; ++n) |     for (unsigned int n = 0; n < v.list.length; ++n) | ||||||
|         v.list.elems[n] = state.maybeThunk(env, elems[n]); |         v.list.elems[n] = elems[n]->maybeThunk(state, env); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -716,7 +715,7 @@ void ExprApp::eval(EvalState & state, Env & env, Value & v) | ||||||
| { | { | ||||||
|     Value vFun; |     Value vFun; | ||||||
|     state.eval(env, e1, vFun); |     state.eval(env, e1, vFun); | ||||||
|     state.callFunction(vFun, *state.maybeThunk(env, e2), v); |     state.callFunction(vFun, *(e2->maybeThunk(state, env)), v); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -791,7 +790,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v) | ||||||
|             if (j == arg.attrs->end()) { |             if (j == arg.attrs->end()) { | ||||||
|                 if (!i->def) throwTypeError("function at %1% called without required argument `%2%'", |                 if (!i->def) throwTypeError("function at %1% called without required argument `%2%'", | ||||||
|                     fun.lambda.fun->pos, i->name); |                     fun.lambda.fun->pos, i->name); | ||||||
|                 env2.values[displ++] = maybeThunk(env2, i->def); |                 env2.values[displ++] = i->def->maybeThunk(*this, env2); | ||||||
|             } else { |             } else { | ||||||
|                 attrsUsed++; |                 attrsUsed++; | ||||||
|                 env2.values[displ++] = j->value; |                 env2.values[displ++] = j->value; | ||||||
|  |  | ||||||
|  | @ -346,8 +346,6 @@ public: | ||||||
|     void mkAttrs(Value & v, unsigned int expected); |     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); |  | ||||||
|      |  | ||||||
|     /* Print statistics. */ |     /* Print statistics. */ | ||||||
|     void printStats(); |     void printStats(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -53,6 +53,7 @@ struct Expr | ||||||
|     virtual void show(std::ostream & str); |     virtual void show(std::ostream & str); | ||||||
|     virtual void bindVars(const StaticEnv & env); |     virtual void bindVars(const StaticEnv & env); | ||||||
|     virtual void eval(EvalState & state, Env & env, Value & v); |     virtual void eval(EvalState & state, Env & env, Value & v); | ||||||
|  |     virtual Value * maybeThunk(EvalState & state, Env & env); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| std::ostream & operator << (std::ostream & str, Expr & e); | std::ostream & operator << (std::ostream & str, Expr & e); | ||||||
|  | @ -117,6 +118,7 @@ struct ExprVar : Expr | ||||||
|     VarRef info; |     VarRef info; | ||||||
|     ExprVar(const Symbol & name) : info(name) { }; |     ExprVar(const Symbol & name) : info(name) { }; | ||||||
|     COMMON_METHODS |     COMMON_METHODS | ||||||
|  |     Value * maybeThunk(EvalState & state, Env & env); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct ExprSelect : Expr | struct ExprSelect : Expr | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue