@@ -2427,12 +2427,12 @@ Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,
2427
2427
if (swift_ast_ctx && (swift_ast_ctx->CheckProcessChanged () ||
2428
2428
swift_ast_ctx->HasFatalErrors ())) {
2429
2429
// If it is safe to replace the scratch context, do so. If
2430
- // try_lock() fails, then higher stack frame (or another
2430
+ // try_lock() fails, then a higher stack frame (or another
2431
2431
// thread) is holding a read lock to the scratch context and
2432
2432
// replacing it could cause a use-after-free later on.
2433
- if ( GetSwiftScratchContextLock (). try_lock ()) {
2434
- auto unlock = llvm::make_scope_exit (
2435
- [ this ] { GetSwiftScratchContextLock (). unlock (); } );
2433
+ auto &lock = GetSwiftScratchContextLock ();
2434
+ if (lock. try_lock ()) {
2435
+ std::lock_guard<std::shared_mutex> unlock (lock, std::adopt_lock );
2436
2436
if (m_use_scratch_typesystem_per_module)
2437
2437
DisplayFallbackSwiftContextErrors (swift_ast_ctx);
2438
2438
else if (StreamSP errs = GetDebugger ().GetAsyncErrorStream ()) {
@@ -2717,66 +2717,77 @@ llvm::Optional<SwiftScratchContextReader> Target::GetSwiftScratchContext(
2717
2717
}
2718
2718
}
2719
2719
}
2720
-
2721
- auto get_or_create_fallback_context =
2722
- [&]() -> TypeSystemSwiftTypeRefForExpressions * {
2723
- if (!lldb_module || !m_use_scratch_typesystem_per_module)
2724
- return nullptr ;
2725
2720
2726
- ModuleLanguage idx = {lldb_module, lldb::eLanguageTypeSwift};
2727
- auto cached = m_scratch_typesystem_for_module.find (idx);
2728
- if (cached != m_scratch_typesystem_for_module.end ()) {
2729
- auto *cached_ts =
2730
- llvm::cast<TypeSystemSwiftTypeRefForExpressions>(cached->second .get ());
2731
- if (!cached_ts)
2732
- return nullptr ;
2721
+ auto get_cached_module_ts =
2722
+ [&](Module *lldb_module) -> TypeSystemSwiftTypeRefForExpressions * {
2723
+ ModuleLanguage key = {lldb_module, lldb::eLanguageTypeSwift};
2724
+ auto cached = m_scratch_typesystem_for_module.find (key);
2725
+ if (cached != m_scratch_typesystem_for_module.end ())
2726
+ return llvm::cast<TypeSystemSwiftTypeRefForExpressions>(cached->second .get ());
2727
+ return nullptr ;
2728
+ };
2729
+
2730
+ auto maybe_create_fallback_context = [&]() {
2731
+ ModuleLanguage key = {lldb_module, lldb::eLanguageTypeSwift};
2732
+ if (auto *cached_ts = get_cached_module_ts (lldb_module)) {
2733
2733
auto *cached_ast_ctx =
2734
2734
llvm::dyn_cast_or_null<SwiftASTContextForExpressions>(
2735
2735
cached_ts->GetSwiftASTContext ());
2736
2736
if (cached_ast_ctx && cached_ast_ctx->HasFatalErrors () &&
2737
2737
!m_cant_make_scratch_type_system.count (lldb::eLanguageTypeSwift)) {
2738
2738
DisplayFallbackSwiftContextErrors (cached_ast_ctx);
2739
2739
// Try again.
2740
- m_scratch_typesystem_for_module.erase (cached);
2741
- return nullptr ;
2740
+ // FIXME: Shouldn't this continue rather than return?
2741
+ auto &lock = GetSwiftScratchContextLock ();
2742
+ if (!lock.try_lock ()) {
2743
+ if (log)
2744
+ log->Printf (" module scratch context has errors but couldn't "
2745
+ " acquire scratch context lock\n " );
2746
+ return ;
2747
+ }
2748
+ std::lock_guard<std::shared_mutex> unlock (lock, std::adopt_lock);
2749
+ m_scratch_typesystem_for_module.erase (key);
2750
+ if (log)
2751
+ log->Printf (" erased module-wide scratch context with errors\n " );
2752
+ return ;
2742
2753
}
2743
2754
if (log)
2744
2755
log->PutCString (" returned cached module-wide scratch context" );
2745
- return cached_ts ;
2756
+ return ;
2746
2757
}
2747
2758
2748
2759
if (!create_on_demand) {
2749
2760
if (log)
2750
2761
log->PutCString (" not allowed to create a new context" );
2751
- return nullptr ;
2762
+ return ;
2752
2763
}
2753
2764
2754
- // Call for its side effects of establishing the Swift scratch type system.
2765
+ // Call for its side effects of establishing the Swift scratch type
2766
+ // system.
2755
2767
auto type_system_or_err =
2756
2768
GetScratchTypeSystemForLanguage (eLanguageTypeSwift, false );
2757
2769
if (!type_system_or_err) {
2758
2770
llvm::consumeError (type_system_or_err.takeError ());
2759
- return nullptr ;
2771
+ return ;
2760
2772
}
2761
2773
2762
- if (!GetSwiftScratchContextLock ().try_lock ()) {
2774
+ auto &lock = GetSwiftScratchContextLock ();
2775
+ if (!lock.try_lock ()) {
2763
2776
if (log)
2764
2777
log->PutCString (" couldn't acquire scratch context lock" );
2765
- return nullptr ;
2778
+ return ;
2766
2779
}
2780
+ std::lock_guard<std::shared_mutex> unlock (lock, std::adopt_lock);
2767
2781
2768
- auto unlock = llvm::make_scope_exit (
2769
- [this ] { GetSwiftScratchContextLock ().unlock (); });
2770
-
2771
- // With the lock held, get the current scratch type system. This ensures the
2772
- // current instance is used even in the unlikely event it was changed during
2773
- // the brief window between the call to `GetScratchTypeSystemForLanguage`
2774
- // and taking the lock.
2782
+ // With the lock held, get the current scratch type system. This ensures
2783
+ // the current instance is used even in the unlikely event it was changed
2784
+ // during the brief window between the call to
2785
+ // `GetScratchTypeSystemForLanguage` and taking the lock.
2775
2786
type_system_or_err = m_scratch_type_system_map.GetTypeSystemForLanguage (
2776
2787
eLanguageTypeSwift, this , false );
2777
2788
if (!type_system_or_err) {
2778
2789
llvm::consumeError (type_system_or_err.takeError ());
2779
- return nullptr ;
2790
+ return ;
2780
2791
}
2781
2792
2782
2793
if (auto *global_scratch_ctx =
@@ -2790,42 +2801,55 @@ llvm::Optional<SwiftScratchContextReader> Target::GetSwiftScratchContext(
2790
2801
auto typesystem_sp = std::make_shared<TypeSystemSwiftTypeRefForExpressions>(
2791
2802
lldb::eLanguageTypeSwift, *this , *lldb_module);
2792
2803
typesystem_sp->GetSwiftASTContext ();
2793
- m_scratch_typesystem_for_module.insert ({idx , typesystem_sp});
2804
+ m_scratch_typesystem_for_module.insert ({key , typesystem_sp});
2794
2805
if (log)
2795
2806
log->PutCString (" created module-wide scratch context" );
2796
- return typesystem_sp. get () ;
2807
+ return ;
2797
2808
};
2798
2809
2799
- auto *swift_scratch_ctx = get_or_create_fallback_context ();
2800
- if (!swift_scratch_ctx) {
2801
- if (log)
2802
- log->PutCString (" returned project-wide scratch context" );
2810
+ llvm::Optional<SwiftScratchContextReader> reader;
2811
+ if (lldb_module && m_use_scratch_typesystem_per_module) {
2812
+ maybe_create_fallback_context ();
2813
+ std::shared_lock<std::shared_mutex> lock (GetSwiftScratchContextLock ());
2814
+ if (auto *cached_ts = get_cached_module_ts (lldb_module)) {
2815
+ reader = SwiftScratchContextReader (std::move (lock), *cached_ts);
2816
+ if (log)
2817
+ log->PutCString (" returned project-wide scratch context" );
2818
+ }
2819
+ }
2820
+ // FIXME: Don't return the project-wide context after requesting the
2821
+ // module-wide one.
2822
+ if (!reader) {
2823
+ std::shared_lock<std::shared_mutex> lock (GetSwiftScratchContextLock ());
2803
2824
auto type_system_or_err =
2804
2825
GetScratchTypeSystemForLanguage (eLanguageTypeSwift, create_on_demand);
2805
- if (type_system_or_err)
2806
- swift_scratch_ctx =
2807
- llvm::cast_or_null<TypeSystemSwiftTypeRefForExpressions>(
2808
- type_system_or_err->get ());
2809
- else
2826
+ if (type_system_or_err) {
2827
+ if (auto *ts = llvm::cast_or_null<TypeSystemSwiftTypeRefForExpressions>(
2828
+ type_system_or_err->get ())) {
2829
+ reader = SwiftScratchContextReader (std::move (lock), *ts);
2830
+ if (log)
2831
+ log->Printf (" returned project-wide scratch context\n " );
2832
+ }
2833
+ } else
2810
2834
llvm::consumeError (type_system_or_err.takeError ());
2811
2835
}
2812
2836
2813
- StackFrameSP frame_sp = exe_scope.CalculateStackFrame ();
2814
- if (frame_sp && frame_sp.get () && swift_scratch_ctx) {
2815
- SymbolContext sc =
2816
- frame_sp->GetSymbolContext (lldb::eSymbolContextEverything);
2817
- Status status = swift_scratch_ctx->PerformCompileUnitImports (sc);
2818
- if (status.Fail ())
2819
- Debugger::ReportError (status.AsCString (), GetDebugger ().GetID ());
2837
+ if (reader) {
2838
+ // Perform compile unit imports.
2839
+ assert (reader->get ());
2840
+ StackFrameSP frame_sp = exe_scope.CalculateStackFrame ();
2841
+ if (frame_sp && frame_sp.get ()) {
2842
+ SymbolContext sc =
2843
+ frame_sp->GetSymbolContext (lldb::eSymbolContextEverything);
2844
+ Status status = reader->get ()->PerformCompileUnitImports (sc);
2845
+ if (status.Fail ())
2846
+ Debugger::ReportError (status.AsCString (), GetDebugger ().GetID ());
2847
+ }
2820
2848
}
2821
-
2822
- if (!swift_scratch_ctx)
2823
- return llvm::None;
2824
- return SwiftScratchContextReader (GetSwiftScratchContextLock (),
2825
- *swift_scratch_ctx);
2849
+ return reader;
2826
2850
}
2827
2851
2828
- static SharedMutex *
2852
+ static std::shared_mutex *
2829
2853
GetSwiftScratchContextMutex (const ExecutionContext *exe_ctx) {
2830
2854
if (!exe_ctx)
2831
2855
return nullptr ;
@@ -2835,11 +2859,20 @@ GetSwiftScratchContextMutex(const ExecutionContext *exe_ctx) {
2835
2859
return nullptr ;
2836
2860
}
2837
2861
2862
+ SwiftScratchContextReader::SwiftScratchContextReader (
2863
+ std::shared_lock<std::shared_mutex> &&lock,
2864
+ TypeSystemSwiftTypeRefForExpressions &ts)
2865
+ : m_lock(std::move(lock)), m_ts(&ts) {}
2866
+
2838
2867
SwiftScratchContextLock::SwiftScratchContextLock (
2839
- const ExecutionContext *exe_ctx)
2840
- : ScopedSharedMutexReader(GetSwiftScratchContextMutex(exe_ctx)) {}
2868
+ const ExecutionContext *exe_ctx) {
2869
+ if (auto *mutex = GetSwiftScratchContextMutex (exe_ctx)) {
2870
+ std::shared_lock<std::shared_mutex> tmp (*mutex);
2871
+ lock.swap (tmp);
2872
+ }
2873
+ }
2841
2874
2842
- static SharedMutex *
2875
+ static std::shared_mutex *
2843
2876
GetSwiftScratchContextMutex (const ExecutionContextRef *exe_ctx_ref) {
2844
2877
if (!exe_ctx_ref)
2845
2878
return nullptr ;
@@ -2848,8 +2881,12 @@ GetSwiftScratchContextMutex(const ExecutionContextRef *exe_ctx_ref) {
2848
2881
}
2849
2882
2850
2883
SwiftScratchContextLock::SwiftScratchContextLock (
2851
- const ExecutionContextRef *exe_ctx_ref)
2852
- : ScopedSharedMutexReader(GetSwiftScratchContextMutex(exe_ctx_ref)) {}
2884
+ const ExecutionContextRef *exe_ctx_ref) {
2885
+ if (auto *mutex = GetSwiftScratchContextMutex (exe_ctx_ref)) {
2886
+ std::shared_lock<std::shared_mutex> tmp (*mutex);
2887
+ lock.swap (tmp);
2888
+ }
2889
+ }
2853
2890
2854
2891
void Target::DisplayFallbackSwiftContextErrors (
2855
2892
SwiftASTContextForExpressions *swift_ast_ctx) {
0 commit comments