From: Nico Weber Date: Sat, 21 Mar 2015 04:11:31 +0000 (-0700) Subject: Recover slowdown for cyclic rule bindings fix. X-Git-Tag: v1.6.0^2~18^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4d44291739222e453421a237ff77d9e5daaa3dd4;p=platform%2Fupstream%2Fninja.git Recover slowdown for cyclic rule bindings fix. --- diff --git a/src/graph.cc b/src/graph.cc index 41055ec..d99c8bd 100644 --- a/src/graph.cc +++ b/src/graph.cc @@ -217,7 +217,7 @@ struct EdgeEnv : public Env { enum EscapeKind { kShellEscape, kDoNotEscape }; EdgeEnv(Edge* edge, EscapeKind escape) - : edge_(edge), escape_in_out_(escape) {} + : edge_(edge), escape_in_out_(escape), recursive_(false) {} virtual string LookupVariable(const string& var); /// Given a span of Nodes, construct a list of paths suitable for a command @@ -226,9 +226,11 @@ struct EdgeEnv : public Env { vector::iterator end, char sep); + private: vector lookups_; Edge* edge_; EscapeKind escape_in_out_; + bool recursive_; }; string EdgeEnv::LookupVariable(const string& var) { @@ -244,19 +246,25 @@ string EdgeEnv::LookupVariable(const string& var) { ' '); } - vector::const_iterator it; - if ((it = find(lookups_.begin(), lookups_.end(), var)) != lookups_.end()) { - string cycle; - for (; it != lookups_.end(); ++it) - cycle.append(*it + " -> "); - cycle.append(var); - Fatal(("cycle in rule variables: " + cycle).c_str()); + if (recursive_) { + vector::const_iterator it; + if ((it = find(lookups_.begin(), lookups_.end(), var)) != lookups_.end()) { + string cycle; + for (; it != lookups_.end(); ++it) + cycle.append(*it + " -> "); + cycle.append(var); + Fatal(("cycle in rule variables: " + cycle).c_str()); + } } // See notes on BindingEnv::LookupWithFallback. const EvalString* eval = edge_->rule_->GetBinding(var); - if (eval) + if (recursive_ && eval) lookups_.push_back(var); + + // In practice, variables defined on rules never use another rule variable. + // For performance, only start checking for cycles after the first lookup. + recursive_ = true; return edge_->env_->LookupWithFallback(var, eval, this); }