From dd8c1d84699bb6b45ffa1a529d53fe2273c8b427 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 11 Feb 2014 12:19:01 -0800 Subject: [PATCH] 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. --- src/manifest_parser.cc | 9 +++++---- 1 file 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); -- 2.7.4