Skip to content

Commit 6df1237

Browse files
authored
Merge pull request #64652 from artemcm/59ProtecSharedScannerState
[5.9][Dependency Scanning] Isolate shared dependency scanner state
2 parents bb8470f + 642d893 commit 6df1237

File tree

5 files changed

+103
-68
lines changed

5 files changed

+103
-68
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/ADT/ArrayRef.h"
2626
#include "llvm/ADT/Optional.h"
2727
#include "llvm/ADT/StringSet.h"
28+
#include "llvm/Support/Mutex.h"
2829
#include <string>
2930
#include <vector>
3031
#include <unordered_map>
@@ -580,18 +581,20 @@ class SwiftDependencyScanningService {
580581
llvm::StringMap<std::unique_ptr<ContextSpecificGlobalCacheState>>
581582
ContextSpecificCacheMap;
582583

583-
/// The current context hash configuration
584-
Optional<std::string> CurrentContextHash;
585-
586584
/// The context hashes used by scanners using this cache, in the order in
587585
/// which they were used
588586
std::vector<std::string> AllContextHashes;
589587

588+
/// Shared state mutual-exclusivity lock
589+
llvm::sys::SmartMutex<true> ScanningServiceGlobalLock;
590+
590591
/// Retrieve the dependencies map that corresponds to the given dependency
591592
/// kind.
592-
ModuleNameToDependencyMap &getDependenciesMap(ModuleDependencyKind kind);
593+
ModuleNameToDependencyMap &getDependenciesMap(ModuleDependencyKind kind,
594+
StringRef scanContextHash);
593595
const ModuleNameToDependencyMap &
594-
getDependenciesMap(ModuleDependencyKind kind) const;
596+
getDependenciesMap(ModuleDependencyKind kind,
597+
StringRef scanContextHash) const;
595598

596599
public:
597600
SwiftDependencyScanningService();
@@ -613,8 +616,8 @@ class SwiftDependencyScanningService {
613616
return *SharedFilesystemCache;
614617
}
615618

616-
llvm::StringSet<>& getAlreadySeenClangModules() {
617-
return getCurrentCache()->alreadySeenClangModules;
619+
llvm::StringSet<>& getAlreadySeenClangModules(StringRef scanningContextHash) {
620+
return getCacheForScanningContextHash(scanningContextHash)->alreadySeenClangModules;
618621
}
619622

620623
/// Wrap the filesystem on the specified `CompilerInstance` with a
@@ -630,7 +633,7 @@ class SwiftDependencyScanningService {
630633

631634
/// Configure the current state of the cache to respond to queries
632635
/// for the specified scanning context hash.
633-
void configureForContextHash(std::string scanningContextHash);
636+
void configureForContextHash(StringRef scanningContextHash);
634637

635638
/// Return context hashes of all scanner invocations that have used
636639
/// this cache instance.
@@ -640,15 +643,12 @@ class SwiftDependencyScanningService {
640643

641644
/// Whether we have cached dependency information for the given module.
642645
bool hasDependency(StringRef moduleName,
643-
Optional<ModuleDependencyKind> kind) const;
644-
645-
/// Return a pointer to the context-specific cache state of the current
646-
/// scanning action.
647-
ContextSpecificGlobalCacheState *getCurrentCache() const;
646+
Optional<ModuleDependencyKind> kind,
647+
StringRef scanContextHash) const;
648648

649649
/// Return a pointer to the cache state of the specified context hash.
650650
ContextSpecificGlobalCacheState *
651-
getCacheForScanningContextHash(StringRef scanningContextHash) const;
651+
getCacheForScanningContextHash(StringRef scanContextHash) const;
652652

653653
/// Look for source-based module dependency details
654654
Optional<const ModuleDependencyInfo*>
@@ -659,15 +659,22 @@ class SwiftDependencyScanningService {
659659
/// \returns the cached result, or \c None if there is no cached entry.
660660
Optional<const ModuleDependencyInfo*>
661661
findDependency(StringRef moduleName,
662-
Optional<ModuleDependencyKind> kind) const;
662+
Optional<ModuleDependencyKind> kind,
663+
StringRef scanContextHash) const;
663664

664665
/// Record dependencies for the given module.
665666
const ModuleDependencyInfo *recordDependency(StringRef moduleName,
666-
ModuleDependencyInfo dependencies);
667+
ModuleDependencyInfo dependencies,
668+
StringRef scanContextHash);
669+
670+
/// Record source-module dependencies for the given module.
671+
const ModuleDependencyInfo *recordSourceDependency(StringRef moduleName,
672+
ModuleDependencyInfo dependencies);
667673

668674
/// Update stored dependencies for the given module.
669675
const ModuleDependencyInfo *updateDependency(ModuleDependencyID moduleID,
670-
ModuleDependencyInfo dependencies);
676+
ModuleDependencyInfo dependencies,
677+
StringRef scanContextHash);
671678

672679
/// Reference the list of all module dependencies that are not source-based
673680
/// modules (i.e. interface dependencies, binary dependencies, clang
@@ -727,7 +734,7 @@ class ModuleDependenciesCache {
727734
return clangScanningTool;
728735
}
729736
llvm::StringSet<>& getAlreadySeenClangModules() {
730-
return globalScanningService.getAlreadySeenClangModules();
737+
return globalScanningService.getAlreadySeenClangModules(scannerContextHash);
731738
}
732739

733740
/// Look for module dependencies for a module with the given name

include/swift/DependencyScan/DependencyScanningTool.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ class DependencyScanningTool {
115115
/// command-line options specified in the batch scan input entry.
116116
std::unique_ptr<CompilerArgInstanceCacheMap> VersionedPCMInstanceCacheCache;
117117

118+
/// Shared state mutual-exclusivity lock
119+
llvm::sys::SmartMutex<true> DependencyScanningToolStateLock;
120+
118121
/// A shared consumer that accumulates encountered diagnostics.
119122
DependencyScannerDiagnosticCollectingConsumer CDC;
120123
llvm::BumpPtrAllocator Alloc;

lib/AST/ModuleDependencies.cpp

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,6 @@ void SwiftDependencyScanningService::overlaySharedFilesystemCacheForCompilation(
251251
Instance.getSourceMgr().setFileSystem(depFS);
252252
}
253253

254-
SwiftDependencyScanningService::ContextSpecificGlobalCacheState *
255-
SwiftDependencyScanningService::getCurrentCache() const {
256-
assert(CurrentContextHash.has_value() &&
257-
"Global Module Dependencies Cache not configured with Triple.");
258-
return getCacheForScanningContextHash(CurrentContextHash.value());
259-
}
260-
261254
SwiftDependencyScanningService::ContextSpecificGlobalCacheState *
262255
SwiftDependencyScanningService::getCacheForScanningContextHash(StringRef scanningContextHash) const {
263256
auto contextSpecificCache = ContextSpecificCacheMap.find(scanningContextHash);
@@ -269,8 +262,8 @@ SwiftDependencyScanningService::getCacheForScanningContextHash(StringRef scannin
269262

270263
const ModuleNameToDependencyMap &
271264
SwiftDependencyScanningService::getDependenciesMap(
272-
ModuleDependencyKind kind) const {
273-
auto contextSpecificCache = getCurrentCache();
265+
ModuleDependencyKind kind, StringRef scanContextHash) const {
266+
auto contextSpecificCache = getCacheForScanningContextHash(scanContextHash);
274267
auto it = contextSpecificCache->ModuleDependenciesMap.find(kind);
275268
assert(it != contextSpecificCache->ModuleDependenciesMap.end() &&
276269
"invalid dependency kind");
@@ -279,40 +272,38 @@ SwiftDependencyScanningService::getDependenciesMap(
279272

280273
ModuleNameToDependencyMap &
281274
SwiftDependencyScanningService::getDependenciesMap(
282-
ModuleDependencyKind kind) {
283-
auto contextSpecificCache = getCurrentCache();
275+
ModuleDependencyKind kind, StringRef scanContextHash) {
276+
llvm::sys::SmartScopedLock<true> Lock(ScanningServiceGlobalLock);
277+
auto contextSpecificCache = getCacheForScanningContextHash(scanContextHash);
284278
auto it = contextSpecificCache->ModuleDependenciesMap.find(kind);
285279
assert(it != contextSpecificCache->ModuleDependenciesMap.end() &&
286280
"invalid dependency kind");
287281
return it->second;
288282
}
289283

290-
void SwiftDependencyScanningService::configureForContextHash(std::string scanningContextHash) {
284+
void SwiftDependencyScanningService::configureForContextHash(StringRef scanningContextHash) {
291285
auto knownContext = ContextSpecificCacheMap.find(scanningContextHash);
292-
if (knownContext != ContextSpecificCacheMap.end()) {
293-
// Set the current context and leave the rest as-is
294-
CurrentContextHash = scanningContextHash;
295-
} else {
296-
// First time scanning with this triple, initialize target-specific state.
286+
if (knownContext == ContextSpecificCacheMap.end()) {
287+
// First time scanning with this context, initialize context-specific state.
297288
std::unique_ptr<ContextSpecificGlobalCacheState> contextSpecificCache =
298289
std::make_unique<ContextSpecificGlobalCacheState>();
299290
for (auto kind = ModuleDependencyKind::FirstKind;
300291
kind != ModuleDependencyKind::LastKind; ++kind) {
301292
contextSpecificCache->ModuleDependenciesMap.insert({kind, ModuleNameToDependencyMap()});
302293
}
303-
304-
ContextSpecificCacheMap.insert({scanningContextHash, std::move(contextSpecificCache)});
305-
CurrentContextHash = scanningContextHash;
306-
AllContextHashes.push_back(scanningContextHash);
294+
llvm::sys::SmartScopedLock<true> Lock(ScanningServiceGlobalLock);
295+
ContextSpecificCacheMap.insert({scanningContextHash.str(), std::move(contextSpecificCache)});
296+
AllContextHashes.push_back(scanningContextHash.str());
307297
}
308298
}
309299

310300
Optional<const ModuleDependencyInfo*> SwiftDependencyScanningService::findDependency(
311-
StringRef moduleName, Optional<ModuleDependencyKind> kind) const {
301+
StringRef moduleName, Optional<ModuleDependencyKind> kind,
302+
StringRef scanningContextHash) const {
312303
if (!kind) {
313304
for (auto kind = ModuleDependencyKind::FirstKind;
314305
kind != ModuleDependencyKind::LastKind; ++kind) {
315-
auto dep = findDependency(moduleName, kind);
306+
auto dep = findDependency(moduleName, kind, scanningContextHash);
316307
if (dep.has_value())
317308
return dep.value();
318309
}
@@ -324,7 +315,7 @@ Optional<const ModuleDependencyInfo*> SwiftDependencyScanningService::findDepend
324315
return findSourceModuleDependency(moduleName);
325316
}
326317

327-
const auto &map = getDependenciesMap(kind.value());
318+
const auto &map = getDependenciesMap(kind.value(), scanningContextHash);
328319
auto known = map.find(moduleName);
329320
if (known != map.end())
330321
return &(known->second);
@@ -343,44 +334,55 @@ SwiftDependencyScanningService::findSourceModuleDependency(
343334
}
344335

345336
bool SwiftDependencyScanningService::hasDependency(
346-
StringRef moduleName, Optional<ModuleDependencyKind> kind) const {
347-
return findDependency(moduleName, kind).has_value();
337+
StringRef moduleName, Optional<ModuleDependencyKind> kind,
338+
StringRef scanContextHash) const {
339+
return findDependency(moduleName, kind, scanContextHash).has_value();
348340
}
349341

350342
const ModuleDependencyInfo *SwiftDependencyScanningService::recordDependency(
351-
StringRef moduleName, ModuleDependencyInfo dependencies) {
343+
StringRef moduleName, ModuleDependencyInfo dependencies,
344+
StringRef scanContextHash) {
352345
auto kind = dependencies.getKind();
353346
// Source-based dependencies are recorded independently of the invocation's
354347
// target triple.
355-
if (kind == swift::ModuleDependencyKind::SwiftSource) {
356-
assert(SwiftSourceModuleDependenciesMap.count(moduleName) == 0 &&
357-
"Attempting to record duplicate SwiftSource dependency.");
358-
SwiftSourceModuleDependenciesMap.insert(
359-
{moduleName, std::move(dependencies)});
360-
AllSourceModules.push_back({moduleName.str(), kind});
361-
return &(SwiftSourceModuleDependenciesMap.find(moduleName)->second);
362-
}
348+
if (kind == swift::ModuleDependencyKind::SwiftSource)
349+
return recordSourceDependency(moduleName, std::move(dependencies));
363350

364351
// All other dependencies are recorded according to the target triple of the
365352
// scanning invocation that discovers them.
366-
auto &map = getDependenciesMap(kind);
353+
auto &map = getDependenciesMap(kind, scanContextHash);
367354
map.insert({moduleName, dependencies});
368355
return &(map[moduleName]);
369356
}
370357

358+
const ModuleDependencyInfo *SwiftDependencyScanningService::recordSourceDependency(
359+
StringRef moduleName, ModuleDependencyInfo dependencies) {
360+
llvm::sys::SmartScopedLock<true> Lock(ScanningServiceGlobalLock);
361+
auto kind = dependencies.getKind();
362+
assert(kind == swift::ModuleDependencyKind::SwiftSource && "Expected source module dependncy info");
363+
assert(SwiftSourceModuleDependenciesMap.count(moduleName) == 0 &&
364+
"Attempting to record duplicate SwiftSource dependency.");
365+
SwiftSourceModuleDependenciesMap.insert(
366+
{moduleName, std::move(dependencies)});
367+
AllSourceModules.push_back({moduleName.str(), kind});
368+
return &(SwiftSourceModuleDependenciesMap.find(moduleName)->second);
369+
}
370+
371371
const ModuleDependencyInfo *SwiftDependencyScanningService::updateDependency(
372-
ModuleDependencyID moduleID, ModuleDependencyInfo dependencies) {
372+
ModuleDependencyID moduleID, ModuleDependencyInfo dependencies,
373+
StringRef scanningContextHash) {
373374
auto kind = dependencies.getKind();
374375
// Source-based dependencies
375376
if (kind == swift::ModuleDependencyKind::SwiftSource) {
377+
llvm::sys::SmartScopedLock<true> Lock(ScanningServiceGlobalLock);
376378
assert(SwiftSourceModuleDependenciesMap.count(moduleID.first) == 1 &&
377379
"Attempting to update non-existing Swift Source dependency.");
378380
auto known = SwiftSourceModuleDependenciesMap.find(moduleID.first);
379381
known->second = std::move(dependencies);
380382
return &(known->second);
381383
}
382384

383-
auto &map = getDependenciesMap(moduleID.second);
385+
auto &map = getDependenciesMap(moduleID.second, scanningContextHash);
384386
auto known = map.find(moduleID.first);
385387
assert(known != map.end() && "Not yet added to map");
386388
known->second = std::move(dependencies);
@@ -422,9 +424,10 @@ ModuleDependenciesCache::ModuleDependenciesCache(
422424
Optional<const ModuleDependencyInfo*>
423425
ModuleDependenciesCache::findDependency(
424426
StringRef moduleName, Optional<ModuleDependencyKind> kind) const {
425-
auto optionalDep = globalScanningService.findDependency(moduleName, kind);
426-
// During a scan, only produce the cached source module info for the current module
427-
// under scan.
427+
auto optionalDep = globalScanningService.findDependency(moduleName, kind,
428+
scannerContextHash);
429+
// During a scan, only produce the cached source module info for the current
430+
// module under scan.
428431
if (optionalDep.hasValue()) {
429432
auto dep = optionalDep.getValue();
430433
if (dep->getAsSwiftSourceModule() &&
@@ -446,7 +449,8 @@ void ModuleDependenciesCache::recordDependency(
446449
StringRef moduleName, ModuleDependencyInfo dependencies) {
447450
auto dependenciesKind = dependencies.getKind();
448451
const ModuleDependencyInfo *recordedDependencies =
449-
globalScanningService.recordDependency(moduleName, dependencies);
452+
globalScanningService.recordDependency(moduleName, dependencies,
453+
scannerContextHash);
450454

451455
auto &map = getDependencyReferencesMap(dependenciesKind);
452456
assert(map.count(moduleName) == 0 && "Already added to map");
@@ -455,7 +459,9 @@ void ModuleDependenciesCache::recordDependency(
455459

456460
void ModuleDependenciesCache::updateDependency(
457461
ModuleDependencyID moduleID, ModuleDependencyInfo dependencyInfo) {
458-
const ModuleDependencyInfo *updatedDependencies = globalScanningService.updateDependency(moduleID, dependencyInfo);
462+
const ModuleDependencyInfo *updatedDependencies =
463+
globalScanningService.updateDependency(moduleID, dependencyInfo,
464+
scannerContextHash);
459465
auto &map = getDependencyReferencesMap(moduleID.second);
460466
auto known = map.find(moduleID.first);
461467
if (known != map.end())

lib/DependencyScan/DependencyScanningTool.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,13 @@
2626
namespace swift {
2727
namespace dependencies {
2828

29+
// Global mutex for target info queries since they are executed separately .
30+
llvm::sys::SmartMutex<true> TargetInfoMutex;
31+
2932
llvm::ErrorOr<swiftscan_string_ref_t> getTargetInfo(ArrayRef<const char *> Command,
3033
const char *main_executable_path) {
34+
llvm::sys::SmartScopedLock<true> Lock(TargetInfoMutex);
35+
3136
// We must reset option occurrences because we are handling an unrelated
3237
// command-line to those possibly parsed before using the same tool.
3338
// We must do so because LLVM options parsing is done using a managed
@@ -178,6 +183,7 @@ DependencyScanningTool::getDependencies(
178183
}
179184

180185
void DependencyScanningTool::serializeCache(llvm::StringRef path) {
186+
llvm::sys::SmartScopedLock<true> Lock(DependencyScanningToolStateLock);
181187
SourceManager SM;
182188
DiagnosticEngine Diags(SM);
183189
Diags.addConsumer(CDC);
@@ -186,6 +192,7 @@ void DependencyScanningTool::serializeCache(llvm::StringRef path) {
186192
}
187193

188194
bool DependencyScanningTool::loadCache(llvm::StringRef path) {
195+
llvm::sys::SmartScopedLock<true> Lock(DependencyScanningToolStateLock);
189196
SourceManager SM;
190197
DiagnosticEngine Diags(SM);
191198
Diags.addConsumer(CDC);
@@ -210,6 +217,10 @@ void DependencyScanningTool::resetDiagnostics() {
210217
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
211218
DependencyScanningTool::initScannerForAction(
212219
ArrayRef<const char *> Command) {
220+
// The remainder of this method operates on shared state in the
221+
// scanning service and global LLVM state with:
222+
// llvm::cl::ResetAllOptionOccurrences
223+
llvm::sys::SmartScopedLock<true> Lock(DependencyScanningToolStateLock);
213224
auto instanceOrErr = initCompilerInstanceForScan(Command);
214225
if (instanceOrErr.getError())
215226
return instanceOrErr;

0 commit comments

Comments
 (0)