@@ -2426,12 +2426,12 @@ Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,
24262426 if (swift_ast_ctx && (swift_ast_ctx->CheckProcessChanged () ||
24272427 swift_ast_ctx->HasFatalErrors ())) {
24282428 // If it is safe to replace the scratch context, do so. If
2429- // try_lock() fails, then higher stack frame (or another
2429+ // try_lock() fails, then a higher stack frame (or another
24302430 // thread) is holding a read lock to the scratch context and
24312431 // replacing it could cause a use-after-free later on.
2432- if ( GetSwiftScratchContextLock (). try_lock ()) {
2433- auto unlock = llvm::make_scope_exit (
2434- [ this ] { GetSwiftScratchContextLock (). unlock (); } );
2432+ auto &lock = GetSwiftScratchContextLock ();
2433+ if (lock. try_lock ()) {
2434+ std::lock_guard<std::shared_mutex> unlock (lock, std::adopt_lock );
24352435 if (m_use_scratch_typesystem_per_module)
24362436 DisplayFallbackSwiftContextErrors (swift_ast_ctx);
24372437 else if (StreamSP errs = GetDebugger ().GetAsyncErrorStream ()) {
@@ -2716,66 +2716,77 @@ llvm::Optional<SwiftScratchContextReader> Target::GetSwiftScratchContext(
27162716 }
27172717 }
27182718 }
2719-
2720- auto get_or_create_fallback_context =
2721- [&]() -> TypeSystemSwiftTypeRefForExpressions * {
2722- if (!lldb_module || !m_use_scratch_typesystem_per_module)
2723- return nullptr ;
27242719
2725- ModuleLanguage idx = {lldb_module, lldb::eLanguageTypeSwift};
2726- auto cached = m_scratch_typesystem_for_module.find (idx);
2727- if (cached != m_scratch_typesystem_for_module.end ()) {
2728- auto *cached_ts =
2729- llvm::cast<TypeSystemSwiftTypeRefForExpressions>(cached->second .get ());
2730- if (!cached_ts)
2731- return nullptr ;
2720+ auto get_cached_module_ts =
2721+ [&](Module *lldb_module) -> TypeSystemSwiftTypeRefForExpressions * {
2722+ ModuleLanguage key = {lldb_module, lldb::eLanguageTypeSwift};
2723+ auto cached = m_scratch_typesystem_for_module.find (key);
2724+ if (cached != m_scratch_typesystem_for_module.end ())
2725+ return llvm::cast<TypeSystemSwiftTypeRefForExpressions>(cached->second .get ());
2726+ return nullptr ;
2727+ };
2728+
2729+ auto maybe_create_fallback_context = [&]() {
2730+ ModuleLanguage key = {lldb_module, lldb::eLanguageTypeSwift};
2731+ if (auto *cached_ts = get_cached_module_ts (lldb_module)) {
27322732 auto *cached_ast_ctx =
27332733 llvm::dyn_cast_or_null<SwiftASTContextForExpressions>(
27342734 cached_ts->GetSwiftASTContext ());
27352735 if (cached_ast_ctx && cached_ast_ctx->HasFatalErrors () &&
27362736 !m_cant_make_scratch_type_system.count (lldb::eLanguageTypeSwift)) {
27372737 DisplayFallbackSwiftContextErrors (cached_ast_ctx);
27382738 // Try again.
2739- m_scratch_typesystem_for_module.erase (cached);
2740- return nullptr ;
2739+ // FIXME: Shouldn't this continue rather than return?
2740+ auto &lock = GetSwiftScratchContextLock ();
2741+ if (!lock.try_lock ()) {
2742+ if (log)
2743+ log->Printf (" module scratch context has errors but couldn't "
2744+ " acquire scratch context lock\n " );
2745+ return ;
2746+ }
2747+ std::lock_guard<std::shared_mutex> unlock (lock, std::adopt_lock);
2748+ m_scratch_typesystem_for_module.erase (key);
2749+ if (log)
2750+ log->Printf (" erased module-wide scratch context with errors\n " );
2751+ return ;
27412752 }
27422753 if (log)
27432754 log->Printf (" returned cached module-wide scratch context\n " );
2744- return cached_ts ;
2755+ return ;
27452756 }
27462757
27472758 if (!create_on_demand) {
27482759 if (log)
27492760 log->Printf (" not allowed to create a new context\n " );
2750- return nullptr ;
2761+ return ;
27512762 }
27522763
2753- // Call for its side effects of establishing the Swift scratch type system.
2764+ // Call for its side effects of establishing the Swift scratch type
2765+ // system.
27542766 auto type_system_or_err =
27552767 GetScratchTypeSystemForLanguage (eLanguageTypeSwift, false );
27562768 if (!type_system_or_err) {
27572769 llvm::consumeError (type_system_or_err.takeError ());
2758- return nullptr ;
2770+ return ;
27592771 }
27602772
2761- if (!GetSwiftScratchContextLock ().try_lock ()) {
2773+ auto &lock = GetSwiftScratchContextLock ();
2774+ if (!lock.try_lock ()) {
27622775 if (log)
27632776 log->Printf (" couldn't acquire scratch context lock\n " );
2764- return nullptr ;
2777+ return ;
27652778 }
2779+ std::lock_guard<std::shared_mutex> unlock (lock, std::adopt_lock);
27662780
2767- auto unlock = llvm::make_scope_exit (
2768- [this ] { GetSwiftScratchContextLock ().unlock (); });
2769-
2770- // With the lock held, get the current scratch type system. This ensures the
2771- // current instance is used even in the unlikely event it was changed during
2772- // the brief window between the call to `GetScratchTypeSystemForLanguage`
2773- // and taking the lock.
2781+ // With the lock held, get the current scratch type system. This ensures
2782+ // the current instance is used even in the unlikely event it was changed
2783+ // during the brief window between the call to
2784+ // `GetScratchTypeSystemForLanguage` and taking the lock.
27742785 type_system_or_err = m_scratch_type_system_map.GetTypeSystemForLanguage (
27752786 eLanguageTypeSwift, this , false );
27762787 if (!type_system_or_err) {
27772788 llvm::consumeError (type_system_or_err.takeError ());
2778- return nullptr ;
2789+ return ;
27792790 }
27802791
27812792 if (auto *global_scratch_ctx =
@@ -2789,42 +2800,55 @@ llvm::Optional<SwiftScratchContextReader> Target::GetSwiftScratchContext(
27892800 auto typesystem_sp = std::make_shared<TypeSystemSwiftTypeRefForExpressions>(
27902801 lldb::eLanguageTypeSwift, *this , *lldb_module);
27912802 typesystem_sp->GetSwiftASTContext ();
2792- m_scratch_typesystem_for_module.insert ({idx , typesystem_sp});
2803+ m_scratch_typesystem_for_module.insert ({key , typesystem_sp});
27932804 if (log)
27942805 log->Printf (" created module-wide scratch context\n " );
2795- return typesystem_sp. get () ;
2806+ return ;
27962807 };
27972808
2798- auto *swift_scratch_ctx = get_or_create_fallback_context ();
2799- if (!swift_scratch_ctx) {
2800- if (log)
2801- log->Printf (" returned project-wide scratch context\n " );
2809+ llvm::Optional<SwiftScratchContextReader> reader;
2810+ if (lldb_module && m_use_scratch_typesystem_per_module) {
2811+ maybe_create_fallback_context ();
2812+ std::shared_lock<std::shared_mutex> lock (GetSwiftScratchContextLock ());
2813+ if (auto *cached_ts = get_cached_module_ts (lldb_module)) {
2814+ reader = SwiftScratchContextReader (std::move (lock), *cached_ts);
2815+ if (log)
2816+ log->Printf (" returned module-wide scratch context\n " );
2817+ }
2818+ }
2819+ // FIXME: Don't return the project-wide context after requesting the
2820+ // module-wide one.
2821+ if (!reader) {
2822+ std::shared_lock<std::shared_mutex> lock (GetSwiftScratchContextLock ());
28022823 auto type_system_or_err =
28032824 GetScratchTypeSystemForLanguage (eLanguageTypeSwift, create_on_demand);
2804- if (type_system_or_err)
2805- swift_scratch_ctx =
2806- llvm::cast_or_null<TypeSystemSwiftTypeRefForExpressions>(
2807- type_system_or_err->get ());
2808- else
2825+ if (type_system_or_err) {
2826+ if (auto *ts = llvm::cast_or_null<TypeSystemSwiftTypeRefForExpressions>(
2827+ type_system_or_err->get ())) {
2828+ reader = SwiftScratchContextReader (std::move (lock), *ts);
2829+ if (log)
2830+ log->Printf (" returned project-wide scratch context\n " );
2831+ }
2832+ } else
28092833 llvm::consumeError (type_system_or_err.takeError ());
28102834 }
28112835
2812- StackFrameSP frame_sp = exe_scope.CalculateStackFrame ();
2813- if (frame_sp && frame_sp.get () && swift_scratch_ctx) {
2814- SymbolContext sc =
2815- frame_sp->GetSymbolContext (lldb::eSymbolContextEverything);
2816- Status status = swift_scratch_ctx->PerformCompileUnitImports (sc);
2817- if (status.Fail ())
2818- Debugger::ReportError (status.AsCString (), GetDebugger ().GetID ());
2836+ if (reader) {
2837+ // Perform compile unit imports.
2838+ assert (reader->get ());
2839+ StackFrameSP frame_sp = exe_scope.CalculateStackFrame ();
2840+ if (frame_sp && frame_sp.get ()) {
2841+ SymbolContext sc =
2842+ frame_sp->GetSymbolContext (lldb::eSymbolContextEverything);
2843+ Status status = reader->get ()->PerformCompileUnitImports (sc);
2844+ if (status.Fail ())
2845+ Debugger::ReportError (status.AsCString (), GetDebugger ().GetID ());
2846+ }
28192847 }
2820-
2821- if (!swift_scratch_ctx)
2822- return llvm::None;
2823- return SwiftScratchContextReader (GetSwiftScratchContextLock (),
2824- *swift_scratch_ctx);
2848+ return reader;
28252849}
28262850
2827- static SharedMutex *
2851+ static std::shared_mutex *
28282852GetSwiftScratchContextMutex (const ExecutionContext *exe_ctx) {
28292853 if (!exe_ctx)
28302854 return nullptr ;
@@ -2834,11 +2858,20 @@ GetSwiftScratchContextMutex(const ExecutionContext *exe_ctx) {
28342858 return nullptr ;
28352859}
28362860
2861+ SwiftScratchContextReader::SwiftScratchContextReader (
2862+ std::shared_lock<std::shared_mutex> &&lock,
2863+ TypeSystemSwiftTypeRefForExpressions &ts)
2864+ : m_lock(std::move(lock)), m_ts(&ts) {}
2865+
28372866SwiftScratchContextLock::SwiftScratchContextLock (
2838- const ExecutionContext *exe_ctx)
2839- : ScopedSharedMutexReader(GetSwiftScratchContextMutex(exe_ctx)) {}
2867+ const ExecutionContext *exe_ctx) {
2868+ if (auto *mutex = GetSwiftScratchContextMutex (exe_ctx)) {
2869+ std::shared_lock<std::shared_mutex> tmp (*mutex);
2870+ lock.swap (tmp);
2871+ }
2872+ }
28402873
2841- static SharedMutex *
2874+ static std::shared_mutex *
28422875GetSwiftScratchContextMutex (const ExecutionContextRef *exe_ctx_ref) {
28432876 if (!exe_ctx_ref)
28442877 return nullptr ;
@@ -2847,8 +2880,12 @@ GetSwiftScratchContextMutex(const ExecutionContextRef *exe_ctx_ref) {
28472880}
28482881
28492882SwiftScratchContextLock::SwiftScratchContextLock (
2850- const ExecutionContextRef *exe_ctx_ref)
2851- : ScopedSharedMutexReader(GetSwiftScratchContextMutex(exe_ctx_ref)) {}
2883+ const ExecutionContextRef *exe_ctx_ref) {
2884+ if (auto *mutex = GetSwiftScratchContextMutex (exe_ctx_ref)) {
2885+ std::shared_lock<std::shared_mutex> tmp (*mutex);
2886+ lock.swap (tmp);
2887+ }
2888+ }
28522889
28532890void Target::DisplayFallbackSwiftContextErrors (
28542891 SwiftASTContextForExpressions *swift_ast_ctx) {
0 commit comments