From 426c51d6ea567170e237a66b49d512fab24cd32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 10 Mar 2018 06:40:17 +0100 Subject: [PATCH] Make FileMap thread-safe --- src/librustc/ich/impls_syntax.rs | 33 +++++++++------- src/libsyntax_pos/lib.rs | 67 ++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 52f43fbed7b..289bc753d7f 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -417,24 +417,27 @@ impl<'a> HashStable> for FileMap { src_hash.hash_stable(hcx, hasher); // We only hash the relative position within this filemap - let lines = lines.borrow(); - lines.len().hash_stable(hcx, hasher); - for &line in lines.iter() { - stable_byte_pos(line, start_pos).hash_stable(hcx, hasher); - } + lines.with_lock(|lines| { + lines.len().hash_stable(hcx, hasher); + for &line in lines.iter() { + stable_byte_pos(line, start_pos).hash_stable(hcx, hasher); + } + }); // We only hash the relative position within this filemap - let multibyte_chars = multibyte_chars.borrow(); - multibyte_chars.len().hash_stable(hcx, hasher); - for &char_pos in multibyte_chars.iter() { - stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher); - } + multibyte_chars.with_lock(|multibyte_chars| { + multibyte_chars.len().hash_stable(hcx, hasher); + for &char_pos in multibyte_chars.iter() { + stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher); + } + }); - let non_narrow_chars = non_narrow_chars.borrow(); - non_narrow_chars.len().hash_stable(hcx, hasher); - for &char_pos in non_narrow_chars.iter() { - stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher); - } + non_narrow_chars.with_lock(|non_narrow_chars| { + non_narrow_chars.len().hash_stable(hcx, hasher); + for &char_pos in non_narrow_chars.iter() { + stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher); + } + }); } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index bec46ff3d79..4711d43bfab 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -27,7 +27,7 @@ #![feature(specialization)] use std::borrow::Cow; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::cmp::{self, Ordering}; use std::fmt; use std::hash::{Hasher, Hash}; @@ -699,17 +699,17 @@ pub struct FileMap { pub src_hash: u128, /// The external source code (used for external crates, which will have a `None` /// value as `self.src`. - pub external_src: RefCell, + pub external_src: Lock, /// The start position of this source in the CodeMap pub start_pos: BytePos, /// The end position of this source in the CodeMap pub end_pos: BytePos, /// Locations of lines beginnings in the source code - pub lines: RefCell>, + pub lines: Lock>, /// Locations of multi-byte characters in the source code - pub multibyte_chars: RefCell>, + pub multibyte_chars: Lock>, /// Width of characters that are not narrow in the source code - pub non_narrow_chars: RefCell>, + pub non_narrow_chars: Lock>, /// A hash of the filename, used for speeding up the incr. comp. hashing. pub name_hash: u128, } @@ -839,10 +839,10 @@ impl Decodable for FileMap { end_pos, src: None, src_hash, - external_src: RefCell::new(ExternalSource::AbsentOk), - lines: RefCell::new(lines), - multibyte_chars: RefCell::new(multibyte_chars), - non_narrow_chars: RefCell::new(non_narrow_chars), + external_src: Lock::new(ExternalSource::AbsentOk), + lines: Lock::new(lines), + multibyte_chars: Lock::new(multibyte_chars), + non_narrow_chars: Lock::new(non_narrow_chars), name_hash, }) }) @@ -882,12 +882,12 @@ impl FileMap { crate_of_origin: 0, src: Some(Lrc::new(src)), src_hash, - external_src: RefCell::new(ExternalSource::Unneeded), + external_src: Lock::new(ExternalSource::Unneeded), start_pos, end_pos: Pos::from_usize(end_pos), - lines: RefCell::new(Vec::new()), - multibyte_chars: RefCell::new(Vec::new()), - non_narrow_chars: RefCell::new(Vec::new()), + lines: Lock::new(Vec::new()), + multibyte_chars: Lock::new(Vec::new()), + non_narrow_chars: Lock::new(Vec::new()), name_hash, } } @@ -919,19 +919,24 @@ impl FileMap { if *self.external_src.borrow() == ExternalSource::AbsentOk { let src = get_src(); let mut external_src = self.external_src.borrow_mut(); - if let Some(src) = src { - let mut hasher: StableHasher = StableHasher::new(); - hasher.write(src.as_bytes()); + // Check that no-one else have provided the source while we were getting it + if *external_src == ExternalSource::AbsentOk { + if let Some(src) = src { + let mut hasher: StableHasher = StableHasher::new(); + hasher.write(src.as_bytes()); - if hasher.finish() == self.src_hash { - *external_src = ExternalSource::Present(src); - return true; + if hasher.finish() == self.src_hash { + *external_src = ExternalSource::Present(src); + return true; + } + } else { + *external_src = ExternalSource::AbsentErr; } - } else { - *external_src = ExternalSource::AbsentErr; - } - false + false + } else { + self.src.is_some() || external_src.get_source().is_some() + } } else { self.src.is_some() || self.external_src.borrow().get_source().is_some() } @@ -951,14 +956,16 @@ impl FileMap { } } - let lines = self.lines.borrow(); - let line = if let Some(line) = lines.get(line_number) { - line - } else { - return None; + let begin = { + let lines = self.lines.borrow(); + let line = if let Some(line) = lines.get(line_number) { + line + } else { + return None; + }; + let begin: BytePos = *line - self.start_pos; + begin.to_usize() }; - let begin: BytePos = *line - self.start_pos; - let begin = begin.to_usize(); if let Some(ref src) = self.src { Some(Cow::from(get_until_newline(src, begin)))