[lldb] Use ReadCStringsFromMemory to speed-up AppleObjCClassDescriptorV2::method_t lookup (#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
This commit is contained in:
Felipe de Azevedo Piovezan 2025-12-22 12:43:36 -03:00 committed by GitHub
parent ec18557dee
commit 3cfe144f99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 7 deletions

View File

@ -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) {

View File

@ -173,6 +173,10 @@ private:
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>