diff options
author | Nico Weber <nicolasweber@gmx.de> | 2014-02-11 20:19:01 (GMT) |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2014-02-11 20:24:32 (GMT) |
commit | dd8c1d84699bb6b45ffa1a529d53fe2273c8b427 (patch) | |
tree | af50cf5018ce54c3e3b97d9102d71b332dd4196e | |
parent | 84986af6fdeae3f649f2bf884b20f644bc370e48 (diff) | |
download | Ninja-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.cc | 9 |
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); |