[Target] Introduce Process::GetLanguageRuntimes
authorAlex Langford <apl@fb.com>
Wed, 29 May 2019 18:08:22 +0000 (18:08 +0000)
committerAlex Langford <apl@fb.com>
Wed, 29 May 2019 18:08:22 +0000 (18:08 +0000)
Summary:
Currently there's not really a good way to iterate over the language runtimes a
process has. This is sometimes desirable (as seen in my change to Thread).
Additionally, there's not really a good reason to iterate over every available
language, but rather only over languages for which we have a plugin loaded.

Reviewers: JDevlieghere, davide, jingham

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D62562

llvm-svn: 361999

lldb/include/lldb/Target/Language.h
lldb/include/lldb/Target/Process.h
lldb/source/Target/Language.cpp
lldb/source/Target/Process.cpp
lldb/source/Target/Thread.cpp

index b45a51f..6ea6029 100644 (file)
@@ -264,6 +264,8 @@ public:
   // etc.
   static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language);
 
+  static std::set<lldb::LanguageType> GetSupportedLanguages();
+
   static void GetLanguagesSupportingTypeSystems(
       std::set<lldb::LanguageType> &languages,
       std::set<lldb::LanguageType> &languages_for_expressions);
index 90118c8..2657302 100644 (file)
@@ -2178,6 +2178,9 @@ public:
 
   OperatingSystem *GetOperatingSystem() { return m_os_up.get(); }
 
+  std::vector<LanguageRuntime *>
+  GetLanguageRuntimes(bool retry_if_null = true);
+
   LanguageRuntime *GetLanguageRuntime(lldb::LanguageType language,
                                       bool retry_if_null = true);
 
index a1a388d..3c3ef28 100644 (file)
@@ -348,6 +348,15 @@ LanguageType Language::GetPrimaryLanguage(LanguageType language) {
   }
 }
 
+std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
+  std::set<lldb::LanguageType> supported_languages;
+  ForEach([&](Language *lang) {
+    supported_languages.emplace(lang->GetLanguageType());
+    return true;
+  });
+  return supported_languages;
+}
+
 void Language::GetLanguagesSupportingTypeSystems(
     std::set<lldb::LanguageType> &languages,
     std::set<lldb::LanguageType> &languages_for_expressions) {
index 4162571..c88ef0d 100644 (file)
@@ -44,6 +44,7 @@
 #include "lldb/Target/InstrumentationRuntime.h"
 #include "lldb/Target/JITLoader.h"
 #include "lldb/Target/JITLoaderList.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/MemoryHistory.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -1547,6 +1548,27 @@ const lldb::ABISP &Process::GetABI() {
   return m_abi_sp;
 }
 
+std::vector<LanguageRuntime *>
+Process::GetLanguageRuntimes(bool retry_if_null) {
+  std::vector<LanguageRuntime *> language_runtimes;
+
+  if (m_finalizing)
+    return language_runtimes;
+
+  std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex);
+  // Before we pass off a copy of the language runtimes, we must make sure that
+  // our collection is properly populated. It's possible that some of the
+  // language runtimes were not loaded yet, either because nobody requested it
+  // yet or the proper condition for loading wasn't yet met (e.g. libc++.so
+  // hadn't been loaded).
+  for (const lldb::LanguageType lang_type : Language::GetSupportedLanguages()) {
+    if (LanguageRuntime *runtime = GetLanguageRuntime(lang_type, retry_if_null))
+      language_runtimes.emplace_back(runtime);
+  }
+
+  return language_runtimes;
+}
+
 LanguageRuntime *Process::GetLanguageRuntime(lldb::LanguageType language,
                                              bool retry_if_null) {
   if (m_finalizing)
index 3908652..f248e6b 100644 (file)
@@ -2211,11 +2211,9 @@ ValueObjectSP Thread::GetCurrentException() {
 
   // NOTE: Even though this behavior is generalized, only ObjC is actually
   // supported at the moment.
-  for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes; lang++) {
-    if (auto runtime = GetProcess()->GetLanguageRuntime(
-            static_cast<lldb::LanguageType>(lang)))
-      if (auto e = runtime->GetExceptionObjectForThread(shared_from_this()))
-        return e;
+  for (LanguageRuntime *runtime : GetProcess()->GetLanguageRuntimes()) {
+    if (auto e = runtime->GetExceptionObjectForThread(shared_from_this()))
+      return e;
   }
 
   return ValueObjectSP();
@@ -2228,11 +2226,9 @@ ThreadSP Thread::GetCurrentExceptionBacktrace() {
 
   // NOTE: Even though this behavior is generalized, only ObjC is actually
   // supported at the moment.
-  for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes; lang++) {
-    if (auto runtime = GetProcess()->GetLanguageRuntime(
-            static_cast<lldb::LanguageType>(lang)))
-      if (auto bt = runtime->GetBacktraceThreadFromException(exception))
-        return bt;
+  for (LanguageRuntime *runtime : GetProcess()->GetLanguageRuntimes()) {
+    if (auto bt = runtime->GetBacktraceThreadFromException(exception))
+      return bt;
   }
 
   return ThreadSP();