[Lldb-commits] [lldb] b360dfd - [lldb] Create dependent modules in parallel (#114507)

2024-11-02 Thread via lldb-commits

Author: Jonas Devlieghere
Date: 2024-11-02T09:38:10-07:00
New Revision: b360dfd5031e76c97257ef1b3e90385bf297e8ab

URL: 
https://github.com/llvm/llvm-project/commit/b360dfd5031e76c97257ef1b3e90385bf297e8ab
DIFF: 
https://github.com/llvm/llvm-project/commit/b360dfd5031e76c97257ef1b3e90385bf297e8ab.diff

LOG: [lldb] Create dependent modules in parallel (#114507)

Create dependent modules in parallel in Target::SetExecutableModule.
This change was inspired by #110646 which takes the same approach when
attaching. Jason suggested we could use the same approach when you
create a target in LLDB.

I used Slack for benchmarking, which loads 902 images.

```
Benchmark 1: ./bin/lldb /Applications/Slack.app/Contents/MacOS/Slack
  Time (mean ± σ):  1.225 s ±  0.003 s[User: 3.977 s, System: 1.521 s]
  Range (min … max):1.220 s …  1.229 s10 runs

Benchmark 2: ./bin/lldb /Applications/Slack.app/Contents/MacOS/Slack
  Time (mean ± σ):  3.253 s ±  0.037 s[User: 3.013 s, System: 0.248 s]
  Range (min … max):3.211 s …  3.310 s10 runs
```

We see about a 2x speedup, which matches what Jason saw for the attach
scenario. I also ran this under TSan to confirm this doesn't introduce
any races or deadlocks.

Added: 


Modified: 
lldb/source/Target/Target.cpp

Removed: 




diff  --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 199efae8a728cc..8cd3fa8af6bae1 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -68,6 +68,7 @@
 
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/Support/ThreadPool.h"
 
 #include 
 #include 
@@ -1575,7 +1576,6 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
m_arch.GetSpec().GetTriple().getTriple());
 }
 
-FileSpecList dependent_files;
 ObjectFile *executable_objfile = executable_sp->GetObjectFile();
 bool load_dependents = true;
 switch (load_dependent_files) {
@@ -1591,10 +1591,14 @@ void Target::SetExecutableModule(ModuleSP 
&executable_sp,
 }
 
 if (executable_objfile && load_dependents) {
+  // FileSpecList is not thread safe and needs to be synchronized.
+  FileSpecList dependent_files;
+  std::mutex dependent_files_mutex;
+
+  // ModuleList is thread safe.
   ModuleList added_modules;
-  executable_objfile->GetDependentModules(dependent_files);
-  for (uint32_t i = 0; i < dependent_files.GetSize(); i++) {
-FileSpec dependent_file_spec(dependent_files.GetFileSpecAtIndex(i));
+
+  auto GetDependentModules = [&](FileSpec dependent_file_spec) {
 FileSpec platform_dependent_file_spec;
 if (m_platform_sp)
   m_platform_sp->GetFileWithUUID(dependent_file_spec, nullptr,
@@ -1608,9 +1612,48 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
 if (image_module_sp) {
   added_modules.AppendIfNeeded(image_module_sp, false);
   ObjectFile *objfile = image_module_sp->GetObjectFile();
-  if (objfile)
-objfile->GetDependentModules(dependent_files);
+  if (objfile) {
+// Create a local copy of the dependent file list so we don't have
+// to lock for the whole duration of GetDependentModules.
+FileSpecList dependent_files_copy;
+{
+  std::lock_guard guard(dependent_files_mutex);
+  dependent_files_copy = dependent_files;
+}
+
+// Remember the size of the local copy so we can append only the
+// modules that have been added by GetDependentModules.
+const size_t previous_dependent_files =
+dependent_files_copy.GetSize();
+
+objfile->GetDependentModules(dependent_files_copy);
+
+{
+  std::lock_guard guard(dependent_files_mutex);
+  for (size_t i = previous_dependent_files;
+   i < dependent_files_copy.GetSize(); ++i)
+dependent_files.AppendIfUnique(
+dependent_files_copy.GetFileSpecAtIndex(i));
+}
+  }
+}
+  };
+
+  executable_objfile->GetDependentModules(dependent_files);
+
+  llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool());
+  for (uint32_t i = 0; i < dependent_files.GetSize(); i++) {
+// Process all currently known dependencies in parallel in the 
innermost
+// loop. This may create newly discovered dependencies to be appended 
to
+// dependent_files. We'll deal with these files during the next
+// iteration of the outermost loop.
+{
+  std::lock_guard guard(dependent_files_mutex);
+  for (; i < dependent_files.GetSize(); i++)
+task_group.async(GetDependentModules,
+ dependent_files.GetFileSpecAtIndex(i));
 }
+task_group.wait();

[Lldb-commits] [lldb] [llvm] [DebugInfo] Add explicit visibility macros to CodeView template functions (PR #113102)

2024-11-02 Thread Vassil Vassilev via lldb-commits

vgvassilev wrote:

> The lldb change looks good (you can submit that in its own patch without a 
> review), but you'll probably want to find a different reviewer for the 
> codeview part (I have no idea who's responsible for that these days).

Thank you, maybe @adrian-prantl will know?

https://github.com/llvm/llvm-project/pull/113102
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Create dependent modules in parallel (PR #114507)

2024-11-02 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere closed 
https://github.com/llvm/llvm-project/pull/114507
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Create dependent modules in parallel (PR #114507)

2024-11-02 Thread Jonas Devlieghere via lldb-commits


@@ -1608,9 +1612,48 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
 if (image_module_sp) {
   added_modules.AppendIfNeeded(image_module_sp, false);
   ObjectFile *objfile = image_module_sp->GetObjectFile();
-  if (objfile)
-objfile->GetDependentModules(dependent_files);
+  if (objfile) {
+// Create a local copy of the dependent file list so we don't have
+// to lock for the whole duration of GetDependentModules.
+FileSpecList dependent_files_copy;
+{
+  std::lock_guard guard(dependent_files_mutex);
+  dependent_files_copy = dependent_files;
+}
+
+// Remember the size of the local copy so we can append only the
+// modules that have been added by GetDependentModules.
+const size_t previous_dependent_files =
+dependent_files_copy.GetSize();
+
+objfile->GetDependentModules(dependent_files_copy);
+
+{
+  std::lock_guard guard(dependent_files_mutex);
+  for (size_t i = previous_dependent_files;
+   i < dependent_files_copy.GetSize(); ++i)
+dependent_files.AppendIfUnique(
+dependent_files_copy.GetFileSpecAtIndex(i));
+}
+  }
+}
+  };
+
+  executable_objfile->GetDependentModules(dependent_files);
+
+  llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool());
+  for (uint32_t i = 0; i < dependent_files.GetSize(); i++) {
+// Process all currently known dependencies in parallel in the 
innermost
+// loop. This may create newly discovered dependencies to be appended 
to
+// dependent_files. We'll deal with these files during the next
+// iteration of the outermost loop.
+{
+  std::lock_guard guard(dependent_files_mutex);
+  for (; i < dependent_files.GetSize(); i++)
+task_group.async(GetDependentModules,

JDevlieghere wrote:

It doesn't, but if that becomes a problem we can do the same trick that Jason 
suggested and iterate over a copy of the list here. For now that seems 
unnecessary but hopefully someone will see this comment if that ever changes 
:-) 

https://github.com/llvm/llvm-project/pull/114507
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] 79178ca - [lldb] Highlight "note:" in CommandReturnObject (#114610)

2024-11-02 Thread via lldb-commits

Author: Jonas Devlieghere
Date: 2024-11-02T08:52:32-07:00
New Revision: 79178ca689a8259d19d93320a6299e3d31383ac4

URL: 
https://github.com/llvm/llvm-project/commit/79178ca689a8259d19d93320a6299e3d31383ac4
DIFF: 
https://github.com/llvm/llvm-project/commit/79178ca689a8259d19d93320a6299e3d31383ac4.diff

LOG: [lldb] Highlight "note:" in CommandReturnObject (#114610)

We have helpers to emit warnings and errors. Do the same thing for notes
to they stand out more.

Added: 


Modified: 
lldb/include/lldb/Interpreter/CommandReturnObject.h
lldb/source/Commands/CommandObjectDWIMPrint.cpp
lldb/source/Interpreter/CommandReturnObject.cpp

Removed: 




diff  --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h 
b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index a491a6c1535b11..9fef59337016df 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -110,6 +110,11 @@ class CommandReturnObject {
   void AppendMessageWithFormat(const char *format, ...)
   __attribute__((format(printf, 2, 3)));
 
+  void AppendNote(llvm::StringRef in_string);
+
+  void AppendNoteWithFormat(const char *format, ...)
+  __attribute__((format(printf, 2, 3)));
+
   void AppendWarning(llvm::StringRef in_string);
 
   void AppendWarningWithFormat(const char *format, ...)
@@ -127,6 +132,11 @@ class CommandReturnObject {
 AppendMessage(llvm::formatv(format, std::forward(args)...).str());
   }
 
+  template 
+  void AppendNoteWithFormatv(const char *format, Args &&...args) {
+AppendNote(llvm::formatv(format, std::forward(args)...).str());
+  }
+
   template 
   void AppendWarningWithFormatv(const char *format, Args &&... args) {
 AppendWarning(llvm::formatv(format, std::forward(args)...).str());

diff  --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp 
b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 76bed100dc7291..62c4e74d853ad1 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -121,10 +121,10 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
   if (note_shown)
 return;
 
-  result.GetOutputStream()
-  << "note: object description requested, but type doesn't implement "
- "a custom object description. Consider using \"p\" instead of "
- "\"po\" (this note will only be shown once per debug session).\n";
+  result.AppendNote(
+  "object description requested, but type doesn't implement "
+  "a custom object description. Consider using \"p\" instead of "
+  "\"po\" (this note will only be shown once per debug session).\n");
   note_shown = true;
 }
   };
@@ -164,8 +164,8 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
 StringRef flags;
 if (args.HasArgs())
   flags = args.GetArgString();
-result.AppendMessageWithFormatv("note: ran `frame variable {0}{1}`",
-flags, expr);
+result.AppendNoteWithFormatv("ran `frame variable {0}{1}`", flags,
+ expr);
   }
 
   dump_val_object(*valobj_sp);
@@ -224,8 +224,7 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
   StringRef flags;
   if (args.HasArgs())
 flags = args.GetArgStringWithDelimiter();
-  result.AppendMessageWithFormatv("note: ran `expression {0}{1}`", flags,
-  expr);
+  result.AppendNoteWithFormatv("ran `expression {0}{1}`", flags, expr);
 }
 
 if (valobj_sp->GetError().GetError() != UserExpression::kNoResult)

diff  --git a/lldb/source/Interpreter/CommandReturnObject.cpp 
b/lldb/source/Interpreter/CommandReturnObject.cpp
index 94f5ff608b2aea..2776efbb5ee36d 100644
--- a/lldb/source/Interpreter/CommandReturnObject.cpp
+++ b/lldb/source/Interpreter/CommandReturnObject.cpp
@@ -27,6 +27,12 @@ static llvm::raw_ostream &warning(Stream &strm) {
  << "warning: ";
 }
 
+static llvm::raw_ostream ¬e(Stream &strm) {
+  return llvm::WithColor(strm.AsRawOstream(), llvm::HighlightColor::Note,
+ llvm::ColorMode::Enable)
+ << "note: ";
+}
+
 static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s) {
   bool add_newline = false;
   if (!s.empty()) {
@@ -74,6 +80,18 @@ void CommandReturnObject::AppendMessageWithFormat(const char 
*format, ...) {
   GetOutputStream() << sstrm.GetString();
 }
 
+void CommandReturnObject::AppendNoteWithFormat(const char *format, ...) {
+  if (!format)
+return;
+  va_list args;
+  va_start(args, format);
+  StreamString sstrm;
+  sstrm.PrintfVarArg(format, args);
+  va_end(args);
+
+  note(GetOutputStream()) << sstrm.GetString();
+}
+
 void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) {
   if (!format)
 retur

[Lldb-commits] [lldb] [lldb] Highlight "note:" in CommandReturnObject (PR #114610)

2024-11-02 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere closed 
https://github.com/llvm/llvm-project/pull/114610
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Create dependent modules in parallel (PR #114507)

2024-11-02 Thread Jonas Devlieghere via lldb-commits


@@ -1608,9 +1612,28 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
 if (image_module_sp) {
   added_modules.AppendIfNeeded(image_module_sp, false);
   ObjectFile *objfile = image_module_sp->GetObjectFile();
-  if (objfile)
+  if (objfile) {
+std::lock_guard guard(dependent_files_mutex);
 objfile->GetDependentModules(dependent_files);

JDevlieghere wrote:

Yeah I did. I was hoping for a slight speedup, but the difference was in the 
noise. 

https://github.com/llvm/llvm-project/pull/114507
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits