aboutsummaryrefslogtreecommitdiff
path: root/build2/cc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-07-25 13:39:57 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-07-25 13:39:57 +0200
commitb1a29c378f517a37a7c74104690c81acafc72ca2 (patch)
treecd95f818f4866467ed6b76275b6fdcf0b9fc4279 /build2/cc
parent185e4b00521b3aeb67df250f77d2bb88740b6582 (diff)
Optimize handling of #line directives that don't change file
Diffstat (limited to 'build2/cc')
-rw-r--r--build2/cc/lexer.cxx18
-rw-r--r--build2/cc/lexer.hxx1
2 files changed, 17 insertions, 2 deletions
diff --git a/build2/cc/lexer.cxx b/build2/cc/lexer.cxx
index 7ab1a57..0615941 100644
--- a/build2/cc/lexer.cxx
+++ b/build2/cc/lexer.cxx
@@ -809,7 +809,12 @@ namespace build2
{
const location l (&name_, c.line, c.column);
- string s (move (log_file_).string ()); // Move string rep out.
+ // It is common to have a large number of #line directives that don't
+ // change the file (they seem to be used to track macro locations or
+ // some such). So we are going to optimize for this by comparing the
+ // current path to what's in #line.
+ //
+ string& s (tmp_file_);
s.clear ();
for (char p ('\0'); p != '\"'; ) // Previous character.
@@ -867,7 +872,16 @@ namespace build2
}
}
- log_file_ = path (move (s)); // Move back in.
+ if (log_file_.string () == s)
+ return;
+
+ // Swap the two string buffers.
+ //
+ {
+ string r (move (log_file_).string ()); // Move string rep out.
+ r.swap (s);
+ log_file_ = path (move (r)); // Move back in.
+ }
// If the path is relative, then prefix it with the current working
// directory. Failed that, we will end up with different checksums for
diff --git a/build2/cc/lexer.hxx b/build2/cc/lexer.hxx
index aa24f6a..9dab12b 100644
--- a/build2/cc/lexer.hxx
+++ b/build2/cc/lexer.hxx
@@ -170,6 +170,7 @@ namespace build2
path log_file_;
optional<uint64_t> log_line_;
+ string tmp_file_;
sha256 cs_;
};