aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-17 09:32:20 +0100
committerGitHub <[email protected]>2020-04-17 09:32:20 +0100
commitd426462b487d9b8ec18184fb169b8fcd990a80d5 (patch)
tree5688c83e7d8a9ddd72b5114b4b5fd1cb523d2251
parent8d296be1090b21b60e509c831864ae85feec2490 (diff)
parent02b96d522cc50252b4cb7927cae04248ea6b6193 (diff)
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]>
-rw-r--r--crates/ra_proc_macro_srv/src/dylib.rs72
1 files changed, 35 insertions, 37 deletions
diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs
index ec63d587b..7d6e5d323 100644
--- a/crates/ra_proc_macro_srv/src/dylib.rs
+++ b/crates/ra_proc_macro_srv/src/dylib.rs
@@ -16,55 +16,53 @@ fn invalid_data_err(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> I
16 IoError::new(IoErrorKind::InvalidData, e) 16 IoError::new(IoErrorKind::InvalidData, e)
17} 17}
18 18
19fn get_symbols_from_lib(file: &Path) -> Result<Vec<String>, IoError> { 19fn is_derive_registrar_symbol(symbol: &str) -> bool {
20 symbol.contains(NEW_REGISTRAR_SYMBOL)
21}
22
23fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> {
20 let buffer = std::fs::read(file)?; 24 let buffer = std::fs::read(file)?;
21 let object = Object::parse(&buffer).map_err(invalid_data_err)?; 25 let object = Object::parse(&buffer).map_err(invalid_data_err)?;
22 26
23 match object { 27 match object {
24 Object::Elf(elf) => { 28 Object::Elf(elf) => {
25 let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?; 29 let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?;
26 let names = symbols.iter().map(|s| s.to_string()).collect(); 30 let name =
27 Ok(names) 31 symbols.iter().find(|s| is_derive_registrar_symbol(s)).map(|s| s.to_string());
32 Ok(name)
28 } 33 }
29 Object::PE(pe) => { 34 Object::PE(pe) => {
30 let symbol_names = 35 let name = pe
31 pe.exports.iter().flat_map(|s| s.name).map(|n| n.to_string()).collect(); 36 .exports
32 Ok(symbol_names) 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)
33 } 42 }
34 Object::Mach(mach) => match mach { 43 Object::Mach(Mach::Binary(binary)) => {
35 Mach::Binary(binary) => { 44 let exports = binary.exports().map_err(invalid_data_err)?;
36 let exports = binary.exports().map_err(invalid_data_err)?; 45 let name = exports
37 let names = exports 46 .iter()
38 .into_iter() 47 .map(|s| {
39 .map(|s| { 48 // In macos doc:
40 // In macos doc: 49 // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
41 // 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
42 // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be 51 // prepended with an underscore.
43 // prepended with an underscore. 52 if s.name.starts_with("_") {
44 if s.name.starts_with("_") { 53 &s.name[1..]
45 s.name[1..].to_string() 54 } else {
46 } else { 55 &s.name
47 s.name 56 }
48 } 57 })
49 }) 58 .find(|s| is_derive_registrar_symbol(&s))
50 .collect(); 59 .map(|s| s.to_string());
51 Ok(names) 60 Ok(name)
52 } 61 }
53 Mach::Fat(_) => Ok(vec![]), 62 _ => Ok(None),
54 },
55 Object::Archive(_) | Object::Unknown(_) => Ok(vec![]),
56 } 63 }
57} 64}
58 65
59fn is_derive_registrar_symbol(symbol: &str) -> bool {
60 symbol.contains(NEW_REGISTRAR_SYMBOL)
61}
62
63fn 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
68/// Loads dynamic library in platform dependent manner. 66/// Loads dynamic library in platform dependent manner.
69/// 67///
70/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described 68/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described