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.
This commit is contained in:
commit
41cb42a370
@ -217,7 +217,7 @@ pub fn expand_include_bytes(
|
|||||||
};
|
};
|
||||||
match cx.source_map().load_binary_file(&file) {
|
match cx.source_map().load_binary_file(&file) {
|
||||||
Ok(bytes) => {
|
Ok(bytes) => {
|
||||||
let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes.into()));
|
let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes));
|
||||||
base::MacEager::expr(expr)
|
base::MacEager::expr(expr)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(round_char_boundary)]
|
#![feature(round_char_boundary)]
|
||||||
|
#![feature(read_buf)]
|
||||||
|
#![feature(new_uninit)]
|
||||||
#![deny(rustc::untranslatable_diagnostic)]
|
#![deny(rustc::untranslatable_diagnostic)]
|
||||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::io::BorrowedBuf;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
@ -101,10 +103,13 @@ pub trait FileLoader {
|
|||||||
fn file_exists(&self, path: &Path) -> bool;
|
fn file_exists(&self, path: &Path) -> bool;
|
||||||
|
|
||||||
/// Read the contents of a UTF-8 file into memory.
|
/// 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>;
|
fn read_file(&self, path: &Path) -> io::Result<String>;
|
||||||
|
|
||||||
/// Read the contents of a potentially non-UTF-8 file into memory.
|
/// 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.
|
/// A FileLoader that uses std::fs to load real files.
|
||||||
@ -119,8 +124,16 @@ fn read_file(&self, path: &Path) -> io::Result<String> {
|
|||||||
fs::read_to_string(path)
|
fs::read_to_string(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> {
|
fn read_binary_file(&self, path: &Path) -> io::Result<Lrc<[u8]>> {
|
||||||
fs::read(path)
|
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 @@ pub fn load_file(&self, path: &Path) -> io::Result<Lrc<SourceFile>> {
|
|||||||
///
|
///
|
||||||
/// Unlike `load_file`, guarantees that no normalization like BOM-removal
|
/// Unlike `load_file`, guarantees that no normalization like BOM-removal
|
||||||
/// takes place.
|
/// 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)?;
|
let bytes = self.file_loader.read_binary_file(path)?;
|
||||||
|
|
||||||
// We need to add file to the `SourceMap`, so that it is present
|
// We need to add file to the `SourceMap`, so that it is present
|
||||||
|
Loading…
Reference in New Issue
Block a user