diff options
| author | bors <bors@rust-lang.org> | 2023-08-28 05:15:56 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-08-28 05:15:56 +0000 |
| commit | 41cb42a370b35707a75c79ff9ab6af1191b638fb (patch) | |
| tree | c36b9d3ee534c593067b7b9f1c8e00c1d48e9e3d /compiler/rustc_span/src | |
| parent | f7dd70c3c9edeecdbedf4d80c83317c50a817756 (diff) | |
| parent | f26293dca4a4bc2fa6158964546617a6a34da639 (diff) | |
| download | rust-41cb42a370b35707a75c79ff9ab6af1191b638fb.tar.gz rust-41cb42a370b35707a75c79ff9ab6af1191b638fb.zip | |
Auto merge of #115296 - saethlin:dont-duplicate-allocs, r=jackh726
Load include_bytes! directly into an Lrc This PR deletes an innocent-looking `.into()` that was converting from a `Vec<u8>` to `Lrc<[u8]>`. This has significant runtime and memory overhead when using `include_bytes!` to pull in a large binary file.
Diffstat (limited to 'compiler/rustc_span/src')
| -rw-r--r-- | compiler/rustc_span/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_span/src/source_map.rs | 21 |
2 files changed, 19 insertions, 4 deletions
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index efaed0f68ce..62fe49fe2a2 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -21,6 +21,8 @@ #![feature(rustc_attrs)] #![feature(let_chains)] #![feature(round_char_boundary)] +#![feature(read_buf)] +#![feature(new_uninit)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![allow(internal_features)] diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 983b2ab04a4..1cff021ba41 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -24,6 +24,8 @@ use std::sync::atomic::Ordering; use std::fs; use std::io; +use std::io::BorrowedBuf; +use std::io::Read; #[cfg(test)] mod tests; @@ -101,10 +103,13 @@ pub trait FileLoader { fn file_exists(&self, path: &Path) -> bool; /// Read the contents of a UTF-8 file into memory. + /// This function must return a String because we normalize + /// source files, which may require resizing. fn read_file(&self, path: &Path) -> io::Result<String>; /// Read the contents of a potentially non-UTF-8 file into memory. - fn read_binary_file(&self, path: &Path) -> io::Result<Vec<u8>>; + /// We don't normalize binary files, so we can start in an Lrc. + fn read_binary_file(&self, path: &Path) -> io::Result<Lrc<[u8]>>; } /// A FileLoader that uses std::fs to load real files. @@ -119,8 +124,16 @@ impl FileLoader for RealFileLoader { fs::read_to_string(path) } - fn read_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> { - fs::read(path) + fn read_binary_file(&self, path: &Path) -> io::Result<Lrc<[u8]>> { + let mut file = fs::File::open(path)?; + let len = file.metadata()?.len(); + + let mut bytes = Lrc::new_uninit_slice(len as usize); + let mut buf = BorrowedBuf::from(Lrc::get_mut(&mut bytes).unwrap()); + file.read_buf_exact(buf.unfilled())?; + // SAFETY: If the read_buf_exact call returns Ok(()), then we have + // read len bytes and initialized the buffer. + Ok(unsafe { bytes.assume_init() }) } } @@ -228,7 +241,7 @@ impl SourceMap { /// /// Unlike `load_file`, guarantees that no normalization like BOM-removal /// takes place. - pub fn load_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> { + pub fn load_binary_file(&self, path: &Path) -> io::Result<Lrc<[u8]>> { let bytes = self.file_loader.read_binary_file(path)?; // We need to add file to the `SourceMap`, so that it is present |
