mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Dependency Scanning] Isolate shared dependency scanner state
Using mutual exclusion, ensuring that multiple threads executing dependency scans do not encounter data races on shared mutable state. There are two layers with shared state where we need to be careful: - `DependencyScanningTool`, as the main entity that scanning clients interact with. This tool instantiates compiler instances for individual scans, computing a scanning invocation hash. It needs to remember those instances for future use, and when creating instances it needs to reset LLVM argument processor's global state, meaning all uses of argument processing must be in a critical section. - `SwiftDependencyScanningService`, as the main cache where dependency scanning results are stored. Each individual scan instantiates a `ModuleDependenciesCache`, which uses the scanning service as the underlying storage. The services' storage is segmented to storing dependencies discovered in a scan with a given context hash, which means two different scanning invocations running at the same time will be accessing different locations in its storage, thus not requiring synchronization. But the service still has some shared state that must be protected, such as the collection of discovered source modules, and the map used to query context-hash-specific underlying cache storage.
This commit is contained in:
@@ -319,7 +319,8 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
|
||||
for (const auto &mod : *bridgingModuleDeps)
|
||||
moduleDep.addBridgingModuleDependency(mod, alreadyAdded);
|
||||
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep));
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep),
|
||||
getContextHash());
|
||||
hasCurrentModule = false;
|
||||
break;
|
||||
}
|
||||
@@ -385,7 +386,7 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
|
||||
for (const auto &mod : *bridgingModuleDeps)
|
||||
moduleDep.addBridgingModuleDependency(mod, alreadyAdded);
|
||||
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep));
|
||||
cache.recordSourceDependency(currentModuleName, std::move(moduleDep));
|
||||
hasCurrentModule = false;
|
||||
break;
|
||||
}
|
||||
@@ -419,7 +420,8 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
|
||||
for (const auto &moduleName : *currentModuleImports)
|
||||
moduleDep.addModuleImport(moduleName);
|
||||
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep));
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep),
|
||||
getContextHash());
|
||||
hasCurrentModule = false;
|
||||
break;
|
||||
}
|
||||
@@ -451,7 +453,8 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
|
||||
for (const auto &moduleName : *currentModuleImports)
|
||||
moduleDep.addModuleImport(moduleName);
|
||||
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep));
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep),
|
||||
getContextHash());
|
||||
hasCurrentModule = false;
|
||||
break;
|
||||
}
|
||||
@@ -494,7 +497,8 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
|
||||
for (const auto &moduleName : *currentModuleImports)
|
||||
moduleDep.addModuleImport(moduleName);
|
||||
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep));
|
||||
cache.recordDependency(currentModuleName, std::move(moduleDep),
|
||||
getContextHash());
|
||||
hasCurrentModule = false;
|
||||
break;
|
||||
}
|
||||
@@ -1018,7 +1022,9 @@ void ModuleDependenciesCacheSerializer::collectStringsAndArrays(
|
||||
for (auto &contextHash : cache.getAllContextHashes()) {
|
||||
addIdentifier(contextHash);
|
||||
for (auto &moduleID : cache.getAllNonSourceModules(contextHash)) {
|
||||
auto optionalDependencyInfo = cache.findDependency(moduleID.first, moduleID.second);
|
||||
auto optionalDependencyInfo = cache.findDependency(moduleID.first,
|
||||
moduleID.second,
|
||||
contextHash);
|
||||
assert(optionalDependencyInfo.has_value() && "Expected dependency info.");
|
||||
auto dependencyInfo = optionalDependencyInfo.value();
|
||||
// Add the module's name
|
||||
@@ -1140,7 +1146,9 @@ void ModuleDependenciesCacheSerializer::writeInterModuleDependenciesCache(
|
||||
// has been used with
|
||||
for (auto &contextHash : cache.getAllContextHashes()) {
|
||||
for (auto &moduleID : cache.getAllNonSourceModules(contextHash)) {
|
||||
auto dependencyInfo = cache.findDependency(moduleID.first, moduleID.second);
|
||||
auto dependencyInfo = cache.findDependency(moduleID.first,
|
||||
moduleID.second,
|
||||
contextHash);
|
||||
assert(dependencyInfo.has_value() && "Expected dependency info.");
|
||||
writeModuleInfo(moduleID, contextHash, **dependencyInfo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user