From 02b96d522cc50252b4cb7927cae04248ea6b6193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Fri, 17 Apr 2020 11:12:05 +0300 Subject: Reduce allocations when looking up proc macro decl --- crates/ra_proc_macro_srv/src/dylib.rs | 72 +++++++++++++++++------------------ 1 file changed, 35 insertions(+), 37 deletions(-) (limited to 'crates') 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>) -> I IoError::new(IoErrorKind::InvalidData, e) } -fn get_symbols_from_lib(file: &Path) -> Result, IoError> { +fn is_derive_registrar_symbol(symbol: &str) -> bool { + symbol.contains(NEW_REGISTRAR_SYMBOL) +} + +fn find_registrar_symbol(file: &Path) -> Result, IoError> { let buffer = std::fs::read(file)?; let object = Object::parse(&buffer).map_err(invalid_data_err)?; match object { Object::Elf(elf) => { let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?; - let names = symbols.iter().map(|s| s.to_string()).collect(); - Ok(names) + let name = + symbols.iter().find(|s| is_derive_registrar_symbol(s)).map(|s| s.to_string()); + Ok(name) } Object::PE(pe) => { - let symbol_names = - pe.exports.iter().flat_map(|s| s.name).map(|n| n.to_string()).collect(); - Ok(symbol_names) + let name = pe + .exports + .iter() + .flat_map(|s| s.name) + .find(|s| is_derive_registrar_symbol(s)) + .map(|s| s.to_string()); + Ok(name) } - Object::Mach(mach) => match mach { - Mach::Binary(binary) => { - let exports = binary.exports().map_err(invalid_data_err)?; - let names = exports - .into_iter() - .map(|s| { - // In macos doc: - // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html - // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be - // prepended with an underscore. - if s.name.starts_with("_") { - s.name[1..].to_string() - } else { - s.name - } - }) - .collect(); - Ok(names) - } - Mach::Fat(_) => Ok(vec![]), - }, - Object::Archive(_) | Object::Unknown(_) => Ok(vec![]), + Object::Mach(Mach::Binary(binary)) => { + let exports = binary.exports().map_err(invalid_data_err)?; + let name = exports + .iter() + .map(|s| { + // In macos doc: + // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html + // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be + // prepended with an underscore. + if s.name.starts_with("_") { + &s.name[1..] + } else { + &s.name + } + }) + .find(|s| is_derive_registrar_symbol(&s)) + .map(|s| s.to_string()); + Ok(name) + } + _ => Ok(None), } } -fn is_derive_registrar_symbol(symbol: &str) -> bool { - symbol.contains(NEW_REGISTRAR_SYMBOL) -} - -fn find_registrar_symbol(file: &Path) -> Result, IoError> { - let symbols = get_symbols_from_lib(file)?; - Ok(symbols.into_iter().find(|s| is_derive_registrar_symbol(s))) -} - /// Loads dynamic library in platform dependent manner. /// /// For unix, you have to use RTLD_DEEPBIND flag to escape problems described -- cgit v1.2.3