SymbolVendorMacOSX::CreateInstance() calls LocateMacOSXFilesUsingDebugSymbols(), to the DebugSymbols framework on macOS, to find a dSYM on the local computer or from a remote server. This method constructs a Module, and it finds a dSYM, creates an ObjectFile for it, then calls SymbolVendor::AddSymbolFileRepresentation with that ObjectFile. The location of the dSYM hasn't been recorded in the Module anywhere, so AddSymbolFileRepresentation eventually (under many layers) calls LocateMacOSXFilesUsingDebugSymbols() again. So we call into the DebugSymbols framework twice. It's easy to fix; have SymbolVendorMacOSX::CreateInstance() add the dSYM path we found from the first call into LocateMacOSXFilesUsingDebugSymbols() in the Module before we call AddSymbolFileRepresentation().
The second perf fix is to LocateMacOSXFilesUsingDebugSymbols() so when it is handed a ModuleSpec that has a binary file path, and that file exists, one of the keys we get back from the DebugSymbols framework gives us a "symbol rich binary" (possibly unstripped). This isn't adding anything when we have the dSYM - we can use the original (possibly stripped) binary that we had to begin with. The symbol rich binary may even be over an NFS filesystem, introducing a large performance cost to using it over the local stripped binary.
Pretty straightforward stuff, not sure who to ask for review, this is more my area than anyone else I can think of these days. If anyone has comments, please let me know.
rdar://84576917