I'm addressing a perf issue where DynamicLoaderDarwin has been notified that a batch of solibs have been loaded. It adds them to the target one-by-one with Target::GetSharedModule(), and then calls Target::ModulesDidLoad() to give breakpoints a chance to evaluate for new locations, etc. One of the things we do on ModulesDidLoad is call ProcessGDBRemote::ModulesDidLoad which will send the qSymbol packet to the gdb remote serial protocol stub if it indicates it wants to know a symbol address. Currently, because Target::GetSharedModule() calls ModulesDidLoad, we will send the qSymbol packet many times - an app with hundreds of solibs are not unusual.
This patch renames Target::GetSharedModule to Target::AddModule() which better reflects what it actually does -- given a ModuleSpec set of criteria, it finds that binary on the local system and adds it to the Target, if it isn't already present. This method name has confused all of us at one point or another. As DynamicLoaderWindowsDYLD notes,
// Confusingly, there is no Target::AddSharedModule. Instead, calling // GetSharedModule() with a new module will add it to the module list and // return a corresponding ModuleSP.
It adds a flag to Target::AddModule to suppress notification of the new Module (i.e. don't call ModulesDidLoad) - if the caller does this, the caller must call Target::ModulesDidLoad before resuming execution. I added a description of the method in Target.h to make this clear.
I also had to add flag to ModuleList::Append and ModuleList::AppendIfNeeded. I made these have default values because many uses of this are in a loop creating a standalone ModuleList, and forcing all of them to specify the notify boolean was nonintuitive for those users. When a ModuleList is a part of the Target, it has notifier callback functions, but when it is a standalone object, it doesn't.
I'm trying to think of how to test this -- but the problem I'm directly trying to address, the qSymbol packet being sent for every solib, instead of the # of groups of solib's that are loaded, is something we don't track today. I'll continue to think about it.
rdar://problem/48293064
Pavel had questions about this error. If we specify an error when we call this, is there a way to get a valid module shared pointer back and still get an error? Maybe this should be one of the llvm::ErrorOr return types?