@@ -447,11 +447,45 @@ static bool HasReflectionInfo(ObjectFile *obj_file) {
447
447
return hasReflectionSection;
448
448
}
449
449
450
- SwiftLanguageRuntimeImpl::ReflectionContextInterface *
450
+ SwiftLanguageRuntimeImpl::ThreadSafeReflectionContext
451
451
SwiftLanguageRuntimeImpl::GetReflectionContext () {
452
- if (!m_initialized_reflection_ctx)
453
- SetupReflection ();
454
- return m_reflection_ctx.get ();
452
+ m_reflection_ctx_mutex.lock ();
453
+ SetupReflection ();
454
+ // SetupReflection can potentially fail.
455
+ if (m_initialized_reflection_ctx)
456
+ ProcessModulesToAdd ();
457
+ return {m_reflection_ctx.get (), m_reflection_ctx_mutex};
458
+ }
459
+
460
+ void SwiftLanguageRuntimeImpl::ProcessModulesToAdd () {
461
+ // A snapshot of the modules to be processed. This is necessary because
462
+ // AddModuleToReflectionContext may recursively call into this function again.
463
+ ModuleList modules_to_add_snapshot;
464
+ {
465
+ std::lock_guard<std::recursive_mutex> lock (m_modules_to_add.GetMutex ());
466
+ modules_to_add_snapshot = m_modules_to_add;
467
+ m_modules_to_add.Clear ();
468
+ }
469
+
470
+ if (modules_to_add_snapshot.IsEmpty ())
471
+ return ;
472
+
473
+ auto &target = m_process.GetTarget ();
474
+ auto exe_module = target.GetExecutableModule ();
475
+ Progress progress (
476
+ llvm::formatv (" Setting up Swift reflection for '{0}'" ,
477
+ exe_module->GetFileSpec ().GetFilename ().AsCString ()),
478
+ modules_to_add_snapshot.GetSize ());
479
+
480
+ size_t completion = 0 ;
481
+
482
+ // Add all defered modules to reflection context that were added to
483
+ // the target since this SwiftLanguageRuntime was created.
484
+ modules_to_add_snapshot.ForEach ([&](const ModuleSP &module_sp) -> bool {
485
+ AddModuleToReflectionContext (module_sp);
486
+ progress.Increment (++completion);
487
+ return true ;
488
+ });
455
489
}
456
490
457
491
SwiftMetadataCache *
@@ -463,79 +497,53 @@ SwiftLanguageRuntimeImpl::GetSwiftMetadataCache() {
463
497
464
498
void SwiftLanguageRuntimeImpl::SetupReflection () {
465
499
LLDB_SCOPED_TIMER ();
466
-
467
- // SetupABIBit() iterates of the Target's images and thus needs to
468
- // acquire that ModuleList's lock. We need to acquire this before
469
- // locking m_add_module_mutex, since ModulesDidLoad can also be
470
- // called from a place where that lock is already held:
471
- // + lldb_private::DynamicLoaderDarwin::AddModulesUsingImageInfos()
472
- // + lldb_private::ModuleList::AppendIfNeeded()
473
- // + lldb_private::Target::NotifyModuleAdded()
474
- // + lldb_private::Target::ModulesDidLoad()
475
500
501
+
502
+ std::lock_guard<std::recursive_mutex> lock (m_reflection_ctx_mutex);
503
+ if (m_initialized_reflection_ctx)
504
+ return ;
505
+
476
506
// The global ABI bit is read by the Swift runtime library.
477
507
SetupABIBit ();
478
508
479
- // A copy of the modules that should be added, to prevent mutating the list
480
- // while iterating over it.
481
- ModuleList modules_snapshot;
482
-
483
509
auto &target = m_process.GetTarget ();
484
510
auto exe_module = target.GetExecutableModule ();
485
- {
486
- std::lock_guard<std::recursive_mutex> lock (m_add_module_mutex);
487
- if (m_initialized_reflection_ctx)
488
- return ;
489
-
490
- if (!exe_module) {
491
- LLDB_LOGF (GetLog (LLDBLog::Types), " %s: Failed to get executable module" ,
492
- LLVM_PRETTY_FUNCTION);
493
- m_initialized_reflection_ctx = false ;
494
- return ;
495
- }
496
511
497
- bool objc_interop = (bool )findRuntime (m_process, RuntimeKind::ObjC);
498
- const char *objc_interop_msg =
499
- objc_interop ? " with Objective-C interopability" : " Swift only" ;
500
-
501
- auto &triple = exe_module->GetArchitecture ().GetTriple ();
502
- if (triple.isArch64Bit ()) {
503
- LLDB_LOGF (GetLog (LLDBLog::Types),
504
- " Initializing a 64-bit reflection context (%s) for \" %s\" " ,
505
- triple.str ().c_str (), objc_interop_msg);
506
- m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext64 (
507
- this ->GetMemoryReader (), objc_interop, GetSwiftMetadataCache ());
508
- } else if (triple.isArch32Bit ()) {
509
- LLDB_LOGF (GetLog (LLDBLog::Types),
510
- " Initializing a 32-bit reflection context (%s) for \" %s\" " ,
511
- triple.str ().c_str (), objc_interop_msg);
512
- m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext32 (
513
- this ->GetMemoryReader (), objc_interop, GetSwiftMetadataCache ());
514
- } else {
515
- LLDB_LOGF (GetLog (LLDBLog::Types),
516
- " Could not initialize reflection context for \" %s\" " ,
517
- triple.str ().c_str ());
518
- }
519
-
520
- modules_snapshot = std::move (m_modules_to_add);
521
- m_modules_to_add.Clear ();
522
- m_initialized_reflection_ctx = true ;
512
+ auto *log = GetLog (LLDBLog::Types);
513
+ if (!exe_module) {
514
+ LLDB_LOGF (log, " %s: Failed to get executable module" ,
515
+ LLVM_PRETTY_FUNCTION);
516
+ m_initialized_reflection_ctx = false ;
517
+ return ;
523
518
}
524
519
525
- Progress progress (
526
- llvm::formatv (" Setting up Swift reflection for '{0}'" ,
527
- exe_module->GetFileSpec ().GetFilename ().AsCString ()),
528
- modules_snapshot.GetSize ());
529
-
530
- size_t completion = 0 ;
531
-
532
- // Add all defered modules to reflection context that were added to
533
- // the target since this SwiftLanguageRuntime was created.
534
- modules_snapshot.ForEach ([&](const ModuleSP &module_sp) -> bool {
535
- AddModuleToReflectionContext (module_sp);
536
- progress.Increment (++completion);
537
- return true ;
538
- });
520
+ bool objc_interop = (bool )findRuntime (m_process, RuntimeKind::ObjC);
521
+ const char *objc_interop_msg =
522
+ objc_interop ? " with Objective-C interopability" : " Swift only" ;
523
+
524
+ auto &triple = exe_module->GetArchitecture ().GetTriple ();
525
+ if (triple.isArch64Bit ()) {
526
+ LLDB_LOGF (log, " Initializing a 64-bit reflection context (%s) for \" %s\" " ,
527
+ triple.str ().c_str (), objc_interop_msg);
528
+ m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext64 (
529
+ this ->GetMemoryReader (), objc_interop, GetSwiftMetadataCache ());
530
+ } else if (triple.isArch32Bit ()) {
531
+ LLDB_LOGF (log,
532
+ " Initializing a 32-bit reflection context (%s) for \" %s\" " ,
533
+ triple.str ().c_str (), objc_interop_msg);
534
+ m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext32 (
535
+ this ->GetMemoryReader (), objc_interop, GetSwiftMetadataCache ());
536
+ } else {
537
+ LLDB_LOGF (log,
538
+ " Could not initialize reflection context for \" %s\" " ,
539
+ triple.str ().c_str ());
540
+ }
541
+ // We set m_initialized_reflection_ctx to true here because
542
+ // AddModuleToReflectionContext can potentially call into SetupReflection
543
+ // again (which will early exit). This is safe to do since every other thread
544
+ // using reflection context will have to wait until all the modules are added,
545
+ // since the thread performing the initialization locked the mutex.
546
+ m_initialized_reflection_ctx = true ;
539
547
}
540
548
541
549
bool SwiftLanguageRuntimeImpl::IsABIStable () {
@@ -922,17 +930,9 @@ bool SwiftLanguageRuntimeImpl::AddModuleToReflectionContext(
922
930
}
923
931
924
932
void SwiftLanguageRuntimeImpl::ModulesDidLoad (const ModuleList &module_list) {
925
- // If the reflection context hasn't been initialized, add them to
926
- // the list of deferred modules so they are added in
927
- // SetupReflection(), otherwise add them directly.
928
- std::lock_guard<std::recursive_mutex> lock (m_add_module_mutex);
929
- if (!m_initialized_reflection_ctx)
930
- m_modules_to_add.AppendIfNeeded (module_list);
931
- else
932
- module_list.ForEach ([&](const ModuleSP &module_sp) -> bool {
933
- AddModuleToReflectionContext (module_sp);
934
- return true ;
935
- });
933
+ // The modules will be lazily processed on the next call to
934
+ // GetReflectionContext.
935
+ m_modules_to_add.AppendIfNeeded (module_list);
936
936
}
937
937
938
938
std::string
0 commit comments