From af0b27e01fc23ddeb43d6e48aa810294e526e334 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Oct 2016 09:06:31 +1100 Subject: [PATCH] Don't hash span filenames twice in IchHasher. This significantly reduces the number of bytes hashed by IchHasher. --- .../calculate_svh/svh_visitor.rs | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 51c894e1b78f..09f12d1a7381 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -82,6 +82,8 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { // within the CodeMap. // Also note that we are hashing byte offsets for the column, not unicode // codepoint offsets. For the purpose of the hash that's sufficient. + // Also, hashing filenames is expensive so we avoid doing it twice when the + // span starts and ends in the same file, which is almost always the case. fn hash_span(&mut self, span: Span) { debug_assert!(self.hash_spans); debug!("hash_span: st={:?}", self.st); @@ -98,21 +100,35 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { span.hi }; - let loc1 = self.codemap.byte_pos_to_line_and_col(span.lo); - let loc2 = self.codemap.byte_pos_to_line_and_col(span_hi); - - let expansion_kind = match span.expn_id { + let expn_kind = match span.expn_id { NO_EXPANSION => SawSpanExpnKind::NoExpansion, COMMAND_LINE_EXPN => SawSpanExpnKind::CommandLine, _ => SawSpanExpnKind::SomeExpansion, }; - SawSpan(loc1.as_ref().map(|&(ref fm, line, col)| (&fm.name[..], line, col)), - loc2.as_ref().map(|&(ref fm, line, col)| (&fm.name[..], line, col)), - expansion_kind) - .hash(self.st); + let loc1 = self.codemap.byte_pos_to_line_and_col(span.lo); + let loc1 = loc1.as_ref() + .map(|&(ref fm, line, col)| (&fm.name[..], line, col)) + .unwrap_or(("???", 0, BytePos(0))); - if expansion_kind == SawSpanExpnKind::SomeExpansion { + let loc2 = self.codemap.byte_pos_to_line_and_col(span_hi); + let loc2 = loc2.as_ref() + .map(|&(ref fm, line, col)| (&fm.name[..], line, col)) + .unwrap_or(("???", 0, BytePos(0))); + + let saw = if loc1.0 == loc2.0 { + SawSpan(loc1.0, + loc1.1, loc1.2, + loc2.1, loc2.2, + expn_kind) + } else { + SawSpanTwoFiles(loc1.0, loc1.1, loc1.2, + loc2.0, loc2.1, loc2.2, + expn_kind) + }; + saw.hash(self.st); + + if expn_kind == SawSpanExpnKind::SomeExpansion { let call_site = self.codemap.codemap().source_callsite(span); self.hash_span(call_site); } @@ -184,9 +200,13 @@ enum SawAbiComponent<'a> { SawAssocTypeBinding, SawAttribute(ast::AttrStyle), SawMacroDef, - SawSpan(Option<(&'a str, usize, BytePos)>, - Option<(&'a str, usize, BytePos)>, + SawSpan(&'a str, + usize, BytePos, + usize, BytePos, SawSpanExpnKind), + SawSpanTwoFiles(&'a str, usize, BytePos, + &'a str, usize, BytePos, + SawSpanExpnKind), } /// SawExprComponent carries all of the information that we want