summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2014-02-11 20:19:01 (GMT)
committerNico Weber <nicolasweber@gmx.de>2014-02-11 20:24:32 (GMT)
commitdd8c1d84699bb6b45ffa1a529d53fe2273c8b427 (patch)
treeaf50cf5018ce54c3e3b97d9102d71b332dd4196e
parent84986af6fdeae3f649f2bf884b20f644bc370e48 (diff)
downloadNinja-dd8c1d84699bb6b45ffa1a529d53fe2273c8b427.zip
Ninja-dd8c1d84699bb6b45ffa1a529d53fe2273c8b427.tar.gz
Ninja-dd8c1d84699bb6b45ffa1a529d53fe2273c8b427.tar.bz2
Allocate per-edge BindingEnvs lazily.
In chrome, only 2000 of 22000 build edges have bindings. A BindingEnv is 64 bytes, so allocating these only when needed saves a bit over 1 MB of memory. Since env chains are shorter for lookups, builds also become a tiny bit faster.
-rw-r--r--src/manifest_parser.cc9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc
index 20be7f3..6fa4f7c 100644
--- a/src/manifest_parser.cc
+++ b/src/manifest_parser.cc
@@ -296,16 +296,17 @@ bool ManifestParser::ParseEdge(string* err) {
if (!ExpectToken(Lexer::NEWLINE, err))
return false;
- // XXX scoped_ptr to handle error case.
- BindingEnv* env = new BindingEnv(env_);
-
- while (lexer_.PeekToken(Lexer::INDENT)) {
+ // Bindings on edges are rare, so allocate per-edge envs only when needed.
+ bool hasIdent = lexer_.PeekToken(Lexer::INDENT);
+ BindingEnv* env = hasIdent ? new BindingEnv(env_) : env_;
+ while (hasIdent) {
string key;
EvalString val;
if (!ParseLet(&key, &val, err))
return false;
env->AddBinding(key, val.Evaluate(env_));
+ hasIdent = lexer_.PeekToken(Lexer::INDENT);
}
Edge* edge = state_->AddEdge(rule);