about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2017-12-08 17:07:48 +0100
committerMichael Woerister <michaelwoerister@posteo>2017-12-14 10:29:16 -0600
commit0b4c2cccac30ebcd436e0cfd77b34019c40d4ce3 (patch)
tree1762e549160fe7c4e8da05530fc7b06ad8ea691a
parent9faa31612fb7a847a1c85836996846b9a6f20116 (diff)
downloadrust-0b4c2cccac30ebcd436e0cfd77b34019c40d4ce3.tar.gz
rust-0b4c2cccac30ebcd436e0cfd77b34019c40d4ce3.zip
incr.comp.: Do less hashing per Span.
-rw-r--r--src/librustc/ich/hcx.rs15
-rw-r--r--src/librustc/ich/impls_syntax.rs2
-rw-r--r--src/librustc/ty/maps/on_disk_cache.rs2
-rw-r--r--src/librustc_metadata/decoder.rs2
-rw-r--r--src/libsyntax/codemap.rs26
-rw-r--r--src/libsyntax_pos/lib.rs56
6 files changed, 62 insertions, 41 deletions
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 2d20836814c..f9fb668110b 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -338,13 +338,16 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
             return std_hash::Hash::hash(&TAG_INVALID_SPAN, hasher);
         }
 
-        let len = span.hi - span.lo;
-
         std_hash::Hash::hash(&TAG_VALID_SPAN, hasher);
-        std_hash::Hash::hash(&file_lo.name, hasher);
-        std_hash::Hash::hash(&line_lo, hasher);
-        std_hash::Hash::hash(&col_lo, hasher);
-        std_hash::Hash::hash(&len, hasher);
+        // We truncate the stable_id hash and line and col numbers. The chances
+        // of causing a collision this way should be minimal.
+        std_hash::Hash::hash(&(file_lo.stable_id.0 as u64), hasher);
+
+        let col = (col_lo.0 as u64) & 0xFF;
+        let line = ((line_lo as u64) & 0xFF_FF_FF) << 8;
+        let len = ((span.hi - span.lo).0 as u64) << 32;
+        let line_col_len = col | line | len;
+        std_hash::Hash::hash(&line_col_len, hasher);
 
         if span.ctxt == SyntaxContext::empty() {
             TAG_NO_EXPANSION.hash_stable(hcx, hasher);
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index c25aa10eb1e..dfb90a5d27f 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -394,6 +394,8 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for FileMap {
             // Do not hash the source as it is not encoded
             src: _,
             src_hash,
+            // The stable id is just a hash of other fields
+            stable_id: _,
             external_src: _,
             start_pos,
             end_pos: _,
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs
index 079b518efd8..7d583a35477 100644
--- a/src/librustc/ty/maps/on_disk_cache.rs
+++ b/src/librustc/ty/maps/on_disk_cache.rs
@@ -176,7 +176,7 @@ impl<'sess> OnDiskCache<'sess> {
                 let index = FileMapIndex(index as u32);
                 let file_ptr: *const FileMap = &**file as *const _;
                 file_to_file_index.insert(file_ptr, index);
-                file_index_to_stable_id.insert(index, StableFilemapId::new(&file));
+                file_index_to_stable_id.insert(index, file.stable_id);
             }
 
             (file_to_file_index, file_index_to_stable_id)
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 49a017535ff..aa7eee366d2 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1124,6 +1124,7 @@ impl<'a, 'tcx> CrateMetadata {
             let syntax_pos::FileMap { name,
                                       name_was_remapped,
                                       src_hash,
+                                      stable_id,
                                       start_pos,
                                       end_pos,
                                       lines,
@@ -1155,6 +1156,7 @@ impl<'a, 'tcx> CrateMetadata {
                                                                    name_was_remapped,
                                                                    self.cnum.as_u32(),
                                                                    src_hash,
+                                                                   stable_id,
                                                                    source_length,
                                                                    lines,
                                                                    multibyte_chars,
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 2c91d60ce9d..07bba29ca4b 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -23,9 +23,7 @@ pub use syntax_pos::hygiene::{ExpnFormat, ExpnInfo, NameAndSpan};
 pub use self::ExpnFormat::*;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::StableHasher;
 use std::cell::{RefCell, Ref};
-use std::hash::Hash;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
 
@@ -102,24 +100,6 @@ impl FileLoader for RealFileLoader {
     }
 }
 
-// This is a FileMap identifier that is used to correlate FileMaps between
-// subsequent compilation sessions (which is something we need to do during
-// incremental compilation).
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
-pub struct StableFilemapId(u128);
-
-impl StableFilemapId {
-    pub fn new(filemap: &FileMap) -> StableFilemapId {
-        let mut hasher = StableHasher::new();
-
-        filemap.name.hash(&mut hasher);
-        filemap.name_was_remapped.hash(&mut hasher);
-        filemap.unmapped_path.hash(&mut hasher);
-
-        StableFilemapId(hasher.finish())
-    }
-}
-
 // _____________________________________________________________________________
 // CodeMap
 //
@@ -217,7 +197,7 @@ impl CodeMap {
 
         self.stable_id_to_filemap
             .borrow_mut()
-            .insert(StableFilemapId::new(&filemap), filemap.clone());
+            .insert(filemap.stable_id, filemap.clone());
 
         filemap
     }
@@ -246,6 +226,7 @@ impl CodeMap {
                                 name_was_remapped: bool,
                                 crate_of_origin: u32,
                                 src_hash: u128,
+                                stable_id: StableFilemapId,
                                 source_len: usize,
                                 mut file_local_lines: Vec<BytePos>,
                                 mut file_local_multibyte_chars: Vec<MultiByteChar>,
@@ -276,6 +257,7 @@ impl CodeMap {
             crate_of_origin,
             src: None,
             src_hash,
+            stable_id,
             external_src: RefCell::new(ExternalSource::AbsentOk),
             start_pos,
             end_pos,
@@ -288,7 +270,7 @@ impl CodeMap {
 
         self.stable_id_to_filemap
             .borrow_mut()
-            .insert(StableFilemapId::new(&filemap), filemap.clone());
+            .insert(stable_id, filemap.clone());
 
         filemap
     }
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 2a381251663..c3d2f0de21d 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -678,6 +678,8 @@ pub struct FileMap {
     pub src: Option<Rc<String>>,
     /// The source code's hash
     pub src_hash: u128,
+    /// The stable id used during incr. comp.
+    pub stable_id: StableFilemapId,
     /// The external source code (used for external crates, which will have a `None`
     /// value as `self.src`.
     pub external_src: RefCell<ExternalSource>,
@@ -693,15 +695,37 @@ pub struct FileMap {
     pub non_narrow_chars: RefCell<Vec<NonNarrowChar>>,
 }
 
+// This is a FileMap identifier that is used to correlate FileMaps between
+// subsequent compilation sessions (which is something we need to do during
+// incremental compilation).
+#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
+pub struct StableFilemapId(pub u128);
+
+impl StableFilemapId {
+    pub fn new(name: &FileName,
+               name_was_remapped: bool,
+               unmapped_path: &FileName)
+               -> StableFilemapId {
+        use std::hash::Hash;
+
+        let mut hasher = StableHasher::new();
+        name.hash(&mut hasher);
+        name_was_remapped.hash(&mut hasher);
+        unmapped_path.hash(&mut hasher);
+        StableFilemapId(hasher.finish())
+    }
+}
+
 impl Encodable for FileMap {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_struct("FileMap", 8, |s| {
             s.emit_struct_field("name", 0, |s| self.name.encode(s))?;
             s.emit_struct_field("name_was_remapped", 1, |s| self.name_was_remapped.encode(s))?;
-            s.emit_struct_field("src_hash", 6, |s| self.src_hash.encode(s))?;
-            s.emit_struct_field("start_pos", 2, |s| self.start_pos.encode(s))?;
-            s.emit_struct_field("end_pos", 3, |s| self.end_pos.encode(s))?;
-            s.emit_struct_field("lines", 4, |s| {
+            s.emit_struct_field("src_hash", 2, |s| self.src_hash.encode(s))?;
+            s.emit_struct_field("stable_id", 3, |s| self.stable_id.encode(s))?;
+            s.emit_struct_field("start_pos", 4, |s| self.start_pos.encode(s))?;
+            s.emit_struct_field("end_pos", 5, |s| self.end_pos.encode(s))?;
+            s.emit_struct_field("lines", 6, |s| {
                 let lines = self.lines.borrow();
                 // store the length
                 s.emit_u32(lines.len() as u32)?;
@@ -747,10 +771,10 @@ impl Encodable for FileMap {
 
                 Ok(())
             })?;
-            s.emit_struct_field("multibyte_chars", 5, |s| {
+            s.emit_struct_field("multibyte_chars", 7, |s| {
                 (*self.multibyte_chars.borrow()).encode(s)
             })?;
-            s.emit_struct_field("non_narrow_chars", 7, |s| {
+            s.emit_struct_field("non_narrow_chars", 8, |s| {
                 (*self.non_narrow_chars.borrow()).encode(s)
             })
         })
@@ -765,11 +789,13 @@ impl Decodable for FileMap {
             let name_was_remapped: bool =
                 d.read_struct_field("name_was_remapped", 1, |d| Decodable::decode(d))?;
             let src_hash: u128 =
-                d.read_struct_field("src_hash", 6, |d| Decodable::decode(d))?;
+                d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
+            let stable_id: StableFilemapId =
+                d.read_struct_field("stable_id", 3, |d| Decodable::decode(d))?;
             let start_pos: BytePos =
-                d.read_struct_field("start_pos", 2, |d| Decodable::decode(d))?;
-            let end_pos: BytePos = d.read_struct_field("end_pos", 3, |d| Decodable::decode(d))?;
-            let lines: Vec<BytePos> = d.read_struct_field("lines", 4, |d| {
+                d.read_struct_field("start_pos", 4, |d| Decodable::decode(d))?;
+            let end_pos: BytePos = d.read_struct_field("end_pos", 5, |d| Decodable::decode(d))?;
+            let lines: Vec<BytePos> = d.read_struct_field("lines", 6, |d| {
                 let num_lines: u32 = Decodable::decode(d)?;
                 let mut lines = Vec::with_capacity(num_lines as usize);
 
@@ -798,9 +824,9 @@ impl Decodable for FileMap {
                 Ok(lines)
             })?;
             let multibyte_chars: Vec<MultiByteChar> =
-                d.read_struct_field("multibyte_chars", 5, |d| Decodable::decode(d))?;
+                d.read_struct_field("multibyte_chars", 7, |d| Decodable::decode(d))?;
             let non_narrow_chars: Vec<NonNarrowChar> =
-                d.read_struct_field("non_narrow_chars", 7, |d| Decodable::decode(d))?;
+                d.read_struct_field("non_narrow_chars", 8, |d| Decodable::decode(d))?;
             Ok(FileMap {
                 name,
                 name_was_remapped,
@@ -813,6 +839,7 @@ impl Decodable for FileMap {
                 end_pos,
                 src: None,
                 src_hash,
+                stable_id,
                 external_src: RefCell::new(ExternalSource::AbsentOk),
                 lines: RefCell::new(lines),
                 multibyte_chars: RefCell::new(multibyte_chars),
@@ -840,6 +867,10 @@ impl FileMap {
         hasher.write(src.as_bytes());
         let src_hash = hasher.finish();
 
+        let stable_id = StableFilemapId::new(&name,
+                                             name_was_remapped,
+                                             &unmapped_path);
+
         let end_pos = start_pos.to_usize() + src.len();
 
         FileMap {
@@ -849,6 +880,7 @@ impl FileMap {
             crate_of_origin: 0,
             src: Some(Rc::new(src)),
             src_hash,
+            stable_id,
             external_src: RefCell::new(ExternalSource::Unneeded),
             start_pos,
             end_pos: Pos::from_usize(end_pos),