diff --git a/test/SourceKit/RelatedIdents/run-parser-with-large-stack.swift b/test/SourceKit/RelatedIdents/run-parser-with-large-stack.swift new file mode 100644 index 0000000000000..62c0eefa73dbe --- /dev/null +++ b/test/SourceKit/RelatedIdents/run-parser-with-large-stack.swift @@ -0,0 +1,303 @@ +// This test used to overflow the stack because SwiftParser was run on a background thread with reduced stack size +// RUN: %sourcekitd-test -req=related-idents -pos=%(line + 1):5 %s -- %s +let x = 1 + +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { +if true { diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp index 652011f5dcea8..bf3340a79a07e 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp @@ -174,13 +174,13 @@ namespace SourceKit { void ASTUnit::Implementation::consumeAsync(SwiftASTConsumerRef ConsumerRef, ASTUnitRef ASTRef) { #if defined(_WIN32) - // Windows uses more up for stack space (why?) than macOS/Linux which - // causes stack overflows in a dispatch thread with 64k stack. Passing - // useDeepStack=true means it's given a _beginthreadex thread with an 8MB - // stack. - bool useDeepStack = true; + // Windows uses more up for stack space (why?) than macOS/Linux which + // causes stack overflows in a dispatch thread with 64k stack. Passing + // useDeepStack=true means it's given a _beginthreadex thread with an 8MB + // stack. + bool useDeepStack = true; #else - bool useDeepStack = false; + bool useDeepStack = ConsumerRef->requiresDeepStack(); #endif Queue.dispatch([ASTRef, ConsumerRef]{ SwiftASTConsumer &ASTConsumer = *ConsumerRef; diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h index bcd0c65a8ae30..7e43fe5439d45 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h +++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h @@ -153,6 +153,15 @@ class SwiftASTConsumer : public std::enable_shared_from_this { public: virtual ~SwiftASTConsumer() { } + /// Whether `handlePrimaryAST` should be executed with the same stack size as + /// the main thread. + /// + /// By default, it is assumed that `handlePrimaryAST` does not do a lot of + /// work and it is sufficient to run it on a background thread's stack with + /// reduced size. Set this to `true` if the consumer can perform additional + /// work that might require more stack size, such as invoking SwiftParser. + virtual bool requiresDeepStack() { return false; } + // MARK: Cancellation /// The result of this consumer is no longer of interest to the SourceKit diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp index cc11e3b15e124..8182a9cdc2462 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp @@ -2537,6 +2537,8 @@ void SwiftLangSupport::findRelatedIdentifiersInFile( std::function &)> Receiver; SwiftInvocationRef Invok; + bool requiresDeepStack() override { return true; } + #if SWIFT_BUILD_SWIFT_SYNTAX // FIXME: Don't silently eat errors here. RelatedIdentsResult getRelatedIdents(SourceFile *SrcFile,