@@ -631,7 +631,16 @@ struct SwiftASTManager::Implementation {
631631 });
632632 }
633633
634- ASTProducerRef getASTProducer (SwiftInvocationRef InvokRef);
634+ // / Retrieve the ASTProducer for a given invocation, creating one if needed.
635+ ASTProducerRef getOrCreateASTProducer (SwiftInvocationRef InvokRef);
636+
637+ // / Retrieve the ASTProducer for a given invocation, returning \c nullopt if
638+ // / not present.
639+ std::optional<ASTProducerRef> getASTProducer (SwiftInvocationRef Invok);
640+
641+ // / Updates the cache entry to account for any changes to the ASTProducer
642+ // / for the given invocation.
643+ void updateASTProducer (SwiftInvocationRef Invok);
635644
636645 FileContent
637646 getFileContent (StringRef FilePath, bool IsPrimary,
@@ -780,7 +789,7 @@ void SwiftASTManager::processASTAsync(
780789 const void *OncePerASTToken, SourceKitCancellationToken CancellationToken,
781790 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fileSystem) {
782791 assert (fileSystem);
783- ASTProducerRef Producer = Impl.getASTProducer (InvokRef);
792+ ASTProducerRef Producer = Impl.getOrCreateASTProducer (InvokRef);
784793
785794 Impl.cleanDeletedConsumers ();
786795 {
@@ -816,12 +825,31 @@ void SwiftASTManager::processASTAsync(
816825 });
817826}
818827
828+ std::optional<ASTProducerRef>
829+ SwiftASTManager::Implementation::getASTProducer (SwiftInvocationRef Invok) {
830+ llvm::sys::ScopedLock L (CacheMtx);
831+ return ASTCache.get (Invok->Impl .Key );
832+ }
833+
834+ void SwiftASTManager::Implementation::updateASTProducer (
835+ SwiftInvocationRef Invok) {
836+ llvm::sys::ScopedLock L (CacheMtx);
837+
838+ // Get and set the producer to update its cost in the cache. If we don't
839+ // have a value, then this is a race where we've removed the cached AST, but
840+ // still have a build waiting to complete after cancellation, we don't need
841+ // to do anything in that case.
842+ if (auto Producer = ASTCache.get (Invok->Impl .Key ))
843+ ASTCache.set (Invok->Impl .Key , *Producer);
844+ }
845+
819846void SwiftASTManager::removeCachedAST (SwiftInvocationRef Invok) {
847+ llvm::sys::ScopedLock L (Impl.CacheMtx );
820848 Impl.ASTCache .remove (Invok->Impl .Key );
821849}
822850
823- ASTProducerRef
824- SwiftASTManager::Implementation::getASTProducer ( SwiftInvocationRef InvokRef) {
851+ ASTProducerRef SwiftASTManager::Implementation::getOrCreateASTProducer (
852+ SwiftInvocationRef InvokRef) {
825853 llvm::sys::ScopedLock L (CacheMtx);
826854 std::optional<ASTProducerRef> OptProducer = ASTCache.get (InvokRef->Impl .Key );
827855 if (OptProducer.has_value ())
@@ -1342,7 +1370,7 @@ void ASTProducer::enqueueConsumer(
13421370 [This]() { This->cleanBuildOperations (); });
13431371 // Re-register the object with the cache to update its memory
13441372 // cost.
1345- Mgr->Impl .ASTCache . set (This->InvokRef -> Impl . Key , This );
1373+ Mgr->Impl .updateASTProducer (This->InvokRef );
13461374 }
13471375 };
13481376
0 commit comments