@@ -2426,12 +2426,12 @@ Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,
2426
2426
if (swift_ast_ctx && (swift_ast_ctx->CheckProcessChanged () ||
2427
2427
swift_ast_ctx->HasFatalErrors ())) {
2428
2428
// 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
2430
2430
// thread) is holding a read lock to the scratch context and
2431
2431
// 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 );
2435
2435
if (m_use_scratch_typesystem_per_module)
2436
2436
DisplayFallbackSwiftContextErrors (swift_ast_ctx);
2437
2437
else if (StreamSP errs = GetDebugger ().GetAsyncErrorStream ()) {
@@ -2716,66 +2716,77 @@ llvm::Optional<SwiftScratchContextReader> Target::GetSwiftScratchContext(
2716
2716
}
2717
2717
}
2718
2718
}
2719
-
2720
- auto get_or_create_fallback_context =
2721
- [&]() -> TypeSystemSwiftTypeRefForExpressions * {
2722
- if (!lldb_module || !m_use_scratch_typesystem_per_module)
2723
- return nullptr ;
2724
2719
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)) {
2732
2732
auto *cached_ast_ctx =
2733
2733
llvm::dyn_cast_or_null<SwiftASTContextForExpressions>(
2734
2734
cached_ts->GetSwiftASTContext ());
2735
2735
if (cached_ast_ctx && cached_ast_ctx->HasFatalErrors () &&
2736
2736
!m_cant_make_scratch_type_system.count (lldb::eLanguageTypeSwift)) {
2737
2737
DisplayFallbackSwiftContextErrors (cached_ast_ctx);
2738
2738
// 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 ;
2741
2752
}
2742
2753
if (log)
2743
2754
log->Printf (" returned cached module-wide scratch context\n " );
2744
- return cached_ts ;
2755
+ return ;
2745
2756
}
2746
2757
2747
2758
if (!create_on_demand) {
2748
2759
if (log)
2749
2760
log->Printf (" not allowed to create a new context\n " );
2750
- return nullptr ;
2761
+ return ;
2751
2762
}
2752
2763
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.
2754
2766
auto type_system_or_err =
2755
2767
GetScratchTypeSystemForLanguage (eLanguageTypeSwift, false );
2756
2768
if (!type_system_or_err) {
2757
2769
llvm::consumeError (type_system_or_err.takeError ());
2758
- return nullptr ;
2770
+ return ;
2759
2771
}
2760
2772
2761
- if (!GetSwiftScratchContextLock ().try_lock ()) {
2773
+ auto &lock = GetSwiftScratchContextLock ();
2774
+ if (!lock.try_lock ()) {
2762
2775
if (log)
2763
2776
log->Printf (" couldn't acquire scratch context lock\n " );
2764
- return nullptr ;
2777
+ return ;
2765
2778
}
2779
+ std::lock_guard<std::shared_mutex> unlock (lock, std::adopt_lock);
2766
2780
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.
2774
2785
type_system_or_err = m_scratch_type_system_map.GetTypeSystemForLanguage (
2775
2786
eLanguageTypeSwift, this , false );
2776
2787
if (!type_system_or_err) {
2777
2788
llvm::consumeError (type_system_or_err.takeError ());
2778
- return nullptr ;
2789
+ return ;
2779
2790
}
2780
2791
2781
2792
if (auto *global_scratch_ctx =
@@ -2789,42 +2800,55 @@ llvm::Optional<SwiftScratchContextReader> Target::GetSwiftScratchContext(
2789
2800
auto typesystem_sp = std::make_shared<TypeSystemSwiftTypeRefForExpressions>(
2790
2801
lldb::eLanguageTypeSwift, *this , *lldb_module);
2791
2802
typesystem_sp->GetSwiftASTContext ();
2792
- m_scratch_typesystem_for_module.insert ({idx , typesystem_sp});
2803
+ m_scratch_typesystem_for_module.insert ({key , typesystem_sp});
2793
2804
if (log)
2794
2805
log->Printf (" created module-wide scratch context\n " );
2795
- return typesystem_sp. get () ;
2806
+ return ;
2796
2807
};
2797
2808
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 ());
2802
2823
auto type_system_or_err =
2803
2824
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
2809
2833
llvm::consumeError (type_system_or_err.takeError ());
2810
2834
}
2811
2835
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
+ }
2819
2847
}
2820
-
2821
- if (!swift_scratch_ctx)
2822
- return llvm::None;
2823
- return SwiftScratchContextReader (GetSwiftScratchContextLock (),
2824
- *swift_scratch_ctx);
2848
+ return reader;
2825
2849
}
2826
2850
2827
- static SharedMutex *
2851
+ static std::shared_mutex *
2828
2852
GetSwiftScratchContextMutex (const ExecutionContext *exe_ctx) {
2829
2853
if (!exe_ctx)
2830
2854
return nullptr ;
@@ -2834,11 +2858,20 @@ GetSwiftScratchContextMutex(const ExecutionContext *exe_ctx) {
2834
2858
return nullptr ;
2835
2859
}
2836
2860
2861
+ SwiftScratchContextReader::SwiftScratchContextReader (
2862
+ std::shared_lock<std::shared_mutex> &&lock,
2863
+ TypeSystemSwiftTypeRefForExpressions &ts)
2864
+ : m_lock(std::move(lock)), m_ts(&ts) {}
2865
+
2837
2866
SwiftScratchContextLock::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
+ }
2840
2873
2841
- static SharedMutex *
2874
+ static std::shared_mutex *
2842
2875
GetSwiftScratchContextMutex (const ExecutionContextRef *exe_ctx_ref) {
2843
2876
if (!exe_ctx_ref)
2844
2877
return nullptr ;
@@ -2847,8 +2880,12 @@ GetSwiftScratchContextMutex(const ExecutionContextRef *exe_ctx_ref) {
2847
2880
}
2848
2881
2849
2882
SwiftScratchContextLock::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
+ }
2852
2889
2853
2890
void Target::DisplayFallbackSwiftContextErrors (
2854
2891
SwiftASTContextForExpressions *swift_ast_ctx) {
0 commit comments