mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Serialization] Improve module loading performance
When looking for a Swift module on disk, we were scanning all module search paths if they contain the module we are searching for. In a setup where each module is contained in its own framework search path, this scaled quadratically with the number of modules being imported. E.g. a setup with 100 modules being imported form 100 module search paths could cause on the order of 10,000 checks of `FileSystem::exists`. While these checks are fairly fast (~10µs), they add up to ~100ms. To improve this, perform a first scan of all module search paths and list the files they contain. From this, create a lookup map that maps filenames to the search paths they can be found in. E.g. for ``` searchPath1/ Module1.framework searchPath2/ Module1.framework Module2.swiftmodule ``` we create the following lookup table ``` Module1.framework -> [searchPath1, searchPath2] Module2.swiftmodule -> [searchPath2] ```
This commit is contained in:
@@ -160,38 +160,40 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
|
||||
if (Triple.isOSDarwin())
|
||||
SearchPathOpts.RuntimeLibraryPaths.push_back(DARWIN_OS_LIBRARY_PATH);
|
||||
|
||||
// If this is set, we don't want any runtime import paths.
|
||||
if (SearchPathOpts.SkipRuntimeLibraryImportPaths) {
|
||||
SearchPathOpts.setRuntimeLibraryImportPaths({});
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up the import paths containing the swiftmodules for the libraries in
|
||||
// RuntimeLibraryPath.
|
||||
SearchPathOpts.RuntimeLibraryImportPaths.clear();
|
||||
|
||||
// If this is set, we don't want any runtime import paths.
|
||||
if (SearchPathOpts.SkipRuntimeLibraryImportPaths)
|
||||
return;
|
||||
|
||||
SearchPathOpts.RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
|
||||
std::vector<std::string> RuntimeLibraryImportPaths;
|
||||
RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
|
||||
|
||||
// This is compatibility for <=5.3
|
||||
if (!Triple.isOSDarwin()) {
|
||||
llvm::sys::path::append(LibPath, swift::getMajorArchitectureName(Triple));
|
||||
SearchPathOpts.RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
|
||||
RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
|
||||
}
|
||||
|
||||
if (!SearchPathOpts.SDKPath.empty()) {
|
||||
if (!SearchPathOpts.getSDKPath().empty()) {
|
||||
if (tripleIsMacCatalystEnvironment(Triple)) {
|
||||
LibPath = SearchPathOpts.SDKPath;
|
||||
LibPath = SearchPathOpts.getSDKPath();
|
||||
llvm::sys::path::append(LibPath, "System", "iOSSupport");
|
||||
llvm::sys::path::append(LibPath, "usr", "lib", "swift");
|
||||
SearchPathOpts.RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
|
||||
RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
|
||||
}
|
||||
|
||||
LibPath = SearchPathOpts.SDKPath;
|
||||
LibPath = SearchPathOpts.getSDKPath();
|
||||
llvm::sys::path::append(LibPath, "usr", "lib", "swift");
|
||||
if (!Triple.isOSDarwin()) {
|
||||
llvm::sys::path::append(LibPath, getPlatformNameForTriple(Triple));
|
||||
llvm::sys::path::append(LibPath, swift::getMajorArchitectureName(Triple));
|
||||
}
|
||||
SearchPathOpts.RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
|
||||
RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
|
||||
}
|
||||
SearchPathOpts.setRuntimeLibraryImportPaths(RuntimeLibraryImportPaths);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -259,7 +261,7 @@ void CompilerInvocation::setTargetTriple(const llvm::Triple &Triple) {
|
||||
}
|
||||
|
||||
void CompilerInvocation::setSDKPath(const std::string &Path) {
|
||||
SearchPathOpts.SDKPath = Path;
|
||||
SearchPathOpts.setSDKPath(Path);
|
||||
updateRuntimeLibraryPaths(SearchPathOpts, LangOpts.Target);
|
||||
}
|
||||
|
||||
@@ -1180,14 +1182,20 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts,
|
||||
return std::string(fullPath.str());
|
||||
};
|
||||
|
||||
std::vector<std::string> ImportSearchPaths(Opts.getImportSearchPaths());
|
||||
for (const Arg *A : Args.filtered(OPT_I)) {
|
||||
Opts.ImportSearchPaths.push_back(resolveSearchPath(A->getValue()));
|
||||
ImportSearchPaths.push_back(resolveSearchPath(A->getValue()));
|
||||
}
|
||||
Opts.setImportSearchPaths(ImportSearchPaths);
|
||||
|
||||
std::vector<SearchPathOptions::FrameworkSearchPath> FrameworkSearchPaths(
|
||||
Opts.getFrameworkSearchPaths());
|
||||
for (const Arg *A : Args.filtered(OPT_F, OPT_Fsystem)) {
|
||||
Opts.FrameworkSearchPaths.push_back({resolveSearchPath(A->getValue()),
|
||||
/*isSystem=*/A->getOption().getID() == OPT_Fsystem});
|
||||
FrameworkSearchPaths.push_back(
|
||||
{resolveSearchPath(A->getValue()),
|
||||
/*isSystem=*/A->getOption().getID() == OPT_Fsystem});
|
||||
}
|
||||
Opts.setFrameworkSearchPaths(FrameworkSearchPaths);
|
||||
|
||||
for (const Arg *A : Args.filtered(OPT_L)) {
|
||||
Opts.LibrarySearchPaths.push_back(resolveSearchPath(A->getValue()));
|
||||
@@ -1198,7 +1206,7 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts,
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_sdk))
|
||||
Opts.SDKPath = A->getValue();
|
||||
Opts.setSDKPath(A->getValue());
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_resource_dir))
|
||||
Opts.RuntimeResourcePath = A->getValue();
|
||||
|
||||
Reference in New Issue
Block a user