Skip to content

Commit d426462

Browse files
bors[bot]lnicola
andauthored
Merge #4007
4007: Reduce allocations when looking up proc macro decl r=edwin0cheng a=lnicola `libserde_derive` has about 21K symbols on Linux. It's not much, but let's ~~not be wasteful~~ avoid the allocations anyway. r? @edwin0cheng Co-authored-by: Laurențiu Nicola <[email protected]>
2 parents 8d296be + 02b96d5 commit d426462

File tree

1 file changed

+35
-37
lines changed

1 file changed

+35
-37
lines changed

crates/ra_proc_macro_srv/src/dylib.rs

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,55 +16,53 @@ fn invalid_data_err(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> I
1616
IoError::new(IoErrorKind::InvalidData, e)
1717
}
1818

19-
fn get_symbols_from_lib(file: &Path) -> Result<Vec<String>, IoError> {
19+
fn is_derive_registrar_symbol(symbol: &str) -> bool {
20+
symbol.contains(NEW_REGISTRAR_SYMBOL)
21+
}
22+
23+
fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> {
2024
let buffer = std::fs::read(file)?;
2125
let object = Object::parse(&buffer).map_err(invalid_data_err)?;
2226

2327
match object {
2428
Object::Elf(elf) => {
2529
let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?;
26-
let names = symbols.iter().map(|s| s.to_string()).collect();
27-
Ok(names)
30+
let name =
31+
symbols.iter().find(|s| is_derive_registrar_symbol(s)).map(|s| s.to_string());
32+
Ok(name)
2833
}
2934
Object::PE(pe) => {
30-
let symbol_names =
31-
pe.exports.iter().flat_map(|s| s.name).map(|n| n.to_string()).collect();
32-
Ok(symbol_names)
35+
let name = pe
36+
.exports
37+
.iter()
38+
.flat_map(|s| s.name)
39+
.find(|s| is_derive_registrar_symbol(s))
40+
.map(|s| s.to_string());
41+
Ok(name)
3342
}
34-
Object::Mach(mach) => match mach {
35-
Mach::Binary(binary) => {
36-
let exports = binary.exports().map_err(invalid_data_err)?;
37-
let names = exports
38-
.into_iter()
39-
.map(|s| {
40-
// In macos doc:
41-
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
42-
// Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
43-
// prepended with an underscore.
44-
if s.name.starts_with("_") {
45-
s.name[1..].to_string()
46-
} else {
47-
s.name
48-
}
49-
})
50-
.collect();
51-
Ok(names)
52-
}
53-
Mach::Fat(_) => Ok(vec![]),
54-
},
55-
Object::Archive(_) | Object::Unknown(_) => Ok(vec![]),
43+
Object::Mach(Mach::Binary(binary)) => {
44+
let exports = binary.exports().map_err(invalid_data_err)?;
45+
let name = exports
46+
.iter()
47+
.map(|s| {
48+
// In macos doc:
49+
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
50+
// Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
51+
// prepended with an underscore.
52+
if s.name.starts_with("_") {
53+
&s.name[1..]
54+
} else {
55+
&s.name
56+
}
57+
})
58+
.find(|s| is_derive_registrar_symbol(&s))
59+
.map(|s| s.to_string());
60+
Ok(name)
61+
}
62+
_ => Ok(None),
5663
}
5764
}
5865

59-
fn is_derive_registrar_symbol(symbol: &str) -> bool {
60-
symbol.contains(NEW_REGISTRAR_SYMBOL)
61-
}
62-
63-
fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> {
64-
let symbols = get_symbols_from_lib(file)?;
65-
Ok(symbols.into_iter().find(|s| is_derive_registrar_symbol(s)))
66-
}
67-
6866
/// Loads dynamic library in platform dependent manner.
6967
///
7068
/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described

0 commit comments

Comments
 (0)