[Lldb-commits] [lldb] [lldb] Use ReadCStringsFromMemory to speed-up AppleObjCClassDescriptorV2::method_t lookup (PR #172031)

Felipe de Azevedo Piovezan via lldb-commits lldb-commits at lists.llvm.org
Fri Dec 12 07:58:14 PST 2025


https://github.com/felipepiovezan created https://github.com/llvm/llvm-project/pull/172031

With this improvement, compiling a simple Objective-C program like:

```
int main() {
    @autoreleasepool {
        NSDictionary *mapping = @{ @"one": @1, @"two": @2, @"three": @3 };
        return 0; //breakhere
    }
}
```

And running `expr -O -- mapping[@"one"]`, we can observe the following packet count for the expression evaluation:

```
Before:
  multi mem read ($MultiMemRead)        :    94
  read memory ($x)                      :  1070
After:
  multi mem read ($MultiMemRead)        :   188
  read memory ($x)                      :   665
```

In other words, we save 311 packets.

Depends on:
* https://github.com/llvm/llvm-project/pull/172026


rdar://151850617

>From ad98e78d467cdb43778b3942c0ad7d0c822258b8 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Fri, 12 Dec 2025 12:15:29 +0000
Subject: [PATCH] [lldb] Use ReadCStringsFromMemory to speed-up
 AppleObjCClassDescriptorV2::method_t lookup

With this improvement, compiling a simple Objective-C program like:

```
int main() {
    @autoreleasepool {
        NSDictionary *mapping = @{ @"one": @1, @"two": @2, @"three": @3 };
        return 0; //breakhere
    }
}
```

And running `expr -O -- mapping[@"one"]`, we can observe the following
packet count for the expression evaluation:

Before:
  multi mem read ($MultiMemRead)        :    94
  read memory ($x)                      :  1070
After:
  multi mem read ($MultiMemRead)        :   188
  read memory ($x)                      :   665

In other words, we save 311 packets.

Depends on:
* https://github.com/llvm/llvm-project/pull/172026
---
 .../AppleObjCClassDescriptorV2.cpp            | 31 ++++++++++++++-----
 .../AppleObjCClassDescriptorV2.h              |  4 +++
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index ebde8892d8f62..430f4f0ebc21f 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -265,6 +265,28 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process,
   return true;
 }
 
+void ClassDescriptorV2::method_t::ReadNames(
+    llvm::MutableArrayRef<method_t> methods, Process &process) {
+  std::vector<lldb::addr_t> str_addresses;
+  str_addresses.reserve(2 * methods.size());
+  for (auto &method : methods)
+    str_addresses.push_back(method.m_name_ptr);
+  for (auto &method : methods)
+    str_addresses.push_back(method.m_types_ptr);
+
+  llvm::SmallVector<std::optional<std::string>> read_result =
+      process.ReadCStringsFromMemory(str_addresses);
+  auto names = llvm::MutableArrayRef(read_result).take_front(methods.size());
+  auto types = llvm::MutableArrayRef(read_result).take_back(methods.size());
+
+  for (auto [name_str, type_str, method] : llvm::zip(names, types, methods)) {
+    if (name_str)
+      method.m_name = std::move(*name_str);
+    if (type_str)
+      method.m_types = std::move(*type_str);
+  }
+}
+
 llvm::SmallVector<ClassDescriptorV2::method_t, 0>
 ClassDescriptorV2::ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses,
                                lldb::addr_t relative_string_base_addr,
@@ -301,6 +323,7 @@ ClassDescriptorV2::ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses,
                         is_small, has_direct_sel, has_relative_types);
   }
 
+  method_t::ReadNames(methods, *process);
   return methods;
 }
 
@@ -338,13 +361,7 @@ bool ClassDescriptorV2::method_t::Read(DataExtractor &extractor,
     m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
   }
 
-  Status error;
-  process->ReadCStringFromMemory(m_name_ptr, m_name, error);
-  if (error.Fail())
-    return false;
-
-  process->ReadCStringFromMemory(m_types_ptr, m_types, error);
-  return error.Success();
+  return true;
 }
 
 bool ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr) {
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 8d19b00f1551f..b5cc50a176b4b 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -173,6 +173,10 @@ class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor {
     bool Read(DataExtractor &extractor, Process *process, lldb::addr_t addr,
               lldb::addr_t relative_string_base_addr, bool is_small,
               bool has_direct_sel, bool has_relative_types);
+
+    /// Fill in `m_name` and `m_types` efficiently by batching read requests.
+    static void ReadNames(llvm::MutableArrayRef<method_t> methods,
+                          Process &process);
   };
 
   llvm::SmallVector<method_t, 0>



More information about the lldb-commits mailing list