diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-04-17 09:32:20 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-04-17 09:32:20 +0100 |
commit | d426462b487d9b8ec18184fb169b8fcd990a80d5 (patch) | |
tree | 5688c83e7d8a9ddd72b5114b4b5fd1cb523d2251 /crates | |
parent | 8d296be1090b21b60e509c831864ae85feec2490 (diff) | |
parent | 02b96d522cc50252b4cb7927cae04248ea6b6193 (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]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_proc_macro_srv/src/dylib.rs | 72 |
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 | ||
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> { | ||
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 | ||
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 | |||
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 |