Skip to content

Commit 3e50a83

Browse files
committed
Optimize line_program_add_file
1 parent 996bfd0 commit 3e50a83

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

src/debuginfo/line_info.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use std::ffi::OsStr;
2+
use std::path::{Component, Path};
3+
14
use crate::prelude::*;
25

36
use syntax::source_map::FileName;
@@ -8,22 +11,49 @@ use gimli::write::{
811
Address, AttributeValue, FileId, LineProgram, LineString, LineStringTable, UnitEntryId,
912
};
1013

14+
// OPTIMIZATION: It is cheaper to do this in one pass than using `.parent()` and `.file_name()`.
15+
fn split_path_dir_and_file(path: &Path) -> (&Path, &OsStr) {
16+
let mut iter = path.components();
17+
let file_name = match iter.next_back() {
18+
Some(Component::Normal(p)) => p,
19+
component => {
20+
panic!("Path component {:?} of path {} is an invalid filename", component, path.display());
21+
}
22+
};
23+
let parent = iter.as_path();
24+
(parent, file_name)
25+
}
26+
27+
// OPTIMIZATION: Avoid UTF-8 validation on UNIX.
28+
fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] {
29+
#[cfg(unix)] {
30+
use std::os::unix::ffi::OsStrExt;
31+
return path.as_bytes();
32+
}
33+
#[cfg(not(unix))] {
34+
return path.to_str().unwrap().as_bytes();
35+
}
36+
}
37+
1138
fn line_program_add_file(
1239
line_program: &mut LineProgram,
1340
line_strings: &mut LineStringTable,
1441
file: &FileName,
1542
) -> FileId {
1643
match file {
1744
FileName::Real(path) => {
18-
let dir_name = path.parent().unwrap().to_str().unwrap().as_bytes();
45+
let (dir_path, file_name) = split_path_dir_and_file(path);
46+
let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
47+
let file_name = osstr_as_utf8_bytes(file_name);
48+
1949
let dir_id = if !dir_name.is_empty() {
2050
let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings);
2151
line_program.add_directory(dir_name)
2252
} else {
2353
line_program.default_directory()
2454
};
2555
let file_name = LineString::new(
26-
path.file_name().unwrap().to_str().unwrap().as_bytes(),
56+
file_name,
2757
line_program.encoding(),
2858
line_strings,
2959
);

0 commit comments

Comments
 (0)