@@ -393,29 +393,27 @@ ClassDescriptorV2::ivar_t::Read(Process *process, lldb::addr_t addr) {
393393 return result;
394394}
395395
396- llvm::Expected<ClassDescriptorV2::relative_list_entry_t >
397- ClassDescriptorV2::relative_list_entry_t::Read (Process * process,
398- lldb::addr_t addr ) {
396+ llvm::Expected<llvm::SmallVector< ClassDescriptorV2::relative_list_entry_t > >
397+ ClassDescriptorV2::ReadRelativeListEntries (Process & process,
398+ llvm::ArrayRef< lldb::addr_t > addrs ) {
399399 size_t size = sizeof (uint64_t ); // m_image_index : 16
400400 // m_list_offset : 48
401401
402- DataBufferHeap buffer (size, ' \0 ' );
403- Status error;
404-
405- process->ReadMemory (addr, buffer.GetBytes (), size, error);
406- if (error.Fail ())
407- return llvm::joinErrors (
408- error.takeError (),
409- llvm::createStringErrorV (
410- " Failed to read relative_list_entry_t at address {0:x}" , addr));
411-
412- DataExtractor extractor (buffer.GetBytes (), size, process->GetByteOrder (),
413- process->GetAddressByteSize ());
414- lldb::offset_t cursor = 0 ;
415- uint64_t raw_entry = extractor.GetU64_unchecked (&cursor);
416- uint16_t image_index = raw_entry & 0xFFFF ;
417- int64_t list_offset = llvm::SignExtend64<48 >(raw_entry >> 16 );
418- return relative_list_entry_t {image_index, list_offset};
402+ llvm::SmallVector<std::optional<uint64_t >> raw_entries =
403+ process.ReadUnsignedIntegersFromMemory (addrs, size);
404+
405+ llvm::SmallVector<relative_list_entry_t > results;
406+ results.reserve (addrs.size ());
407+ for (auto [addr, maybe_raw] : llvm::zip (addrs, raw_entries)) {
408+ if (!maybe_raw)
409+ return llvm::createStringErrorV (
410+ " Failed to read relative_list_entry_t at address {0:x}" , addr);
411+ uint64_t raw = *maybe_raw;
412+ uint16_t image_index = raw & 0xFFFF ;
413+ int64_t list_offset = llvm::SignExtend64<48 >(raw >> 16 );
414+ results.push_back (relative_list_entry_t {image_index, list_offset});
415+ }
416+ return results;
419417}
420418
421419llvm::Expected<ClassDescriptorV2::relative_list_list_t >
@@ -505,18 +503,23 @@ llvm::Error ClassDescriptorV2::ProcessRelativeMethodLists(
505503 if (!relative_method_lists)
506504 return relative_method_lists.takeError ();
507505
508- for (uint32_t i = 0 ; i < relative_method_lists->m_count ; i++) {
509- // 2. Extract the image index and the list offset from the
510- // relative_list_entry_t
511- const lldb::addr_t entry_addr = relative_method_lists->m_first_ptr +
512- (i * relative_method_lists->m_entsize );
513- auto entry = relative_list_entry_t::Read (process, entry_addr);
514- if (!entry)
515- return entry.takeError ();
506+ // 2. Compute the address of every relative_list_entry_t and read them all in
507+ // a single batched memory read.
508+ auto to_entry_addr = [&](uint64_t idx) {
509+ return relative_method_lists->m_first_ptr +
510+ (idx * relative_method_lists->m_entsize );
511+ };
512+ auto entry_addrs = llvm::to_vector (llvm::map_range (
513+ llvm::seq<uint64_t >(relative_method_lists->m_count ), to_entry_addr));
514+
515+ auto entries = ReadRelativeListEntries (*process, entry_addrs);
516+ if (!entries)
517+ return entries.takeError ();
516518
519+ for (auto [entry_addr, entry] : llvm::zip (entry_addrs, *entries)) {
517520 // 3. Calculate the pointer to the method_list_t from the
518521 // relative_list_entry_t
519- const lldb::addr_t method_list_addr = entry_addr + entry-> m_list_offset ;
522+ const lldb::addr_t method_list_addr = entry_addr + entry. m_list_offset ;
520523
521524 // 4. Get the method_list_t from the pointer
522525 llvm::Expected<method_list_t > method_list =
@@ -525,10 +528,10 @@ llvm::Error ClassDescriptorV2::ProcessRelativeMethodLists(
525528 return method_list.takeError ();
526529
527530 // 5. Cache the result so we don't need to reconstruct it later.
528- m_image_to_method_lists[entry-> m_image_index ].emplace_back (*method_list);
531+ m_image_to_method_lists[entry. m_image_index ].emplace_back (*method_list);
529532
530533 // 6. If the relevant image is loaded, add the methods to the Decl
531- if (!m_runtime.IsSharedCacheImageLoaded (entry-> m_image_index ))
534+ if (!m_runtime.IsSharedCacheImageLoaded (entry. m_image_index ))
532535 continue ;
533536
534537 ProcessMethodList (instance_method_func, *method_list);
0 commit comments