Skip to content

Commit 4837a8e

Browse files
committed
Introduce ExternalTypeRefInfoProvider
LLDB would like to cache typeref information to accelerate finding type information. This patch adds an optional interface that allows of typeref to register and provider field descriptor information for faster lookups.
1 parent bd10966 commit 4837a8e

File tree

5 files changed

+186
-48
lines changed

5 files changed

+186
-48
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,10 @@ class ReflectionContext
211211
uint32_t ThreadPort;
212212
};
213213

214-
explicit ReflectionContext(std::shared_ptr<MemoryReader> reader)
215-
: super(std::move(reader), *this)
216-
{}
214+
explicit ReflectionContext(
215+
std::shared_ptr<MemoryReader> reader,
216+
remote::ExternalTypeRefInfoProvider *provider = nullptr)
217+
: super(std::move(reader), *this, provider) {}
217218

218219
ReflectionContext(const ReflectionContext &other) = delete;
219220
ReflectionContext &operator=(const ReflectionContext &other) = delete;
@@ -228,7 +229,8 @@ class ReflectionContext
228229
}
229230

230231
template <typename T>
231-
bool readMachOSections(
232+
llvm::Optional<uint64_t>
233+
readMachOSections(
232234
RemoteAddress ImageStart,
233235
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
234236
auto Buf =
@@ -350,7 +352,7 @@ class ReflectionContext
350352
{MPEnumMdSec.first, MPEnumMdSec.second},
351353
PotentialModuleNames};
352354

353-
this->addReflectionInfo(info);
355+
auto InfoID = this->addReflectionInfo(info);
354356

355357
// Find the __DATA segment.
356358
for (unsigned I = 0; I < NumCommands; ++I) {
@@ -374,10 +376,10 @@ class ReflectionContext
374376

375377
savedBuffers.push_back(std::move(Buf));
376378
savedBuffers.push_back(std::move(Sections));
377-
return true;
379+
return InfoID;
378380
}
379381

380-
bool readPECOFFSections(
382+
llvm::Optional<uint64_t> readPECOFFSections(
381383
RemoteAddress ImageStart,
382384
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
383385
auto DOSHdrBuf = this->getReader().readBytes(
@@ -477,11 +479,10 @@ class ReflectionContext
477479
{ConformMdSec.first, ConformMdSec.second},
478480
{MPEnumMdSec.first, MPEnumMdSec.second},
479481
PotentialModuleNames};
480-
this->addReflectionInfo(Info);
481-
return true;
482+
return this->addReflectionInfo(Info);
482483
}
483484

484-
bool readPECOFF(RemoteAddress ImageStart,
485+
llvm::Optional<uint64_t> readPECOFF(RemoteAddress ImageStart,
485486
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
486487
auto Buf = this->getReader().readBytes(ImageStart,
487488
sizeof(llvm::object::dos_header));
@@ -505,7 +506,7 @@ class ReflectionContext
505506
}
506507

507508
template <typename T>
508-
bool readELFSections(
509+
llvm::Optional<uint64_t> readELFSections(
509510
RemoteAddress ImageStart,
510511
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
511512
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
@@ -673,8 +674,7 @@ class ReflectionContext
673674
{MPEnumMdSec.first, MPEnumMdSec.second},
674675
PotentialModuleNames};
675676

676-
this->addReflectionInfo(info);
677-
return true;
677+
return this->addReflectionInfo(info);
678678
}
679679

680680
/// Parses metadata information from an ELF image. Because the Section
@@ -693,22 +693,22 @@ class ReflectionContext
693693
/// instance's memory reader.
694694
///
695695
/// \return
696-
/// /b True if the metadata information was parsed successfully,
697-
/// /b false otherwise.
698-
bool
696+
/// \b The newly added reflection info ID if successful,
697+
/// \b llvm::None otherwise.
698+
llvm::Optional<uint64_t>
699699
readELF(RemoteAddress ImageStart,
700700
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
701701
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
702702
auto Buf =
703703
this->getReader().readBytes(ImageStart, sizeof(llvm::ELF::Elf64_Ehdr));
704704
if (!Buf)
705-
return false;
705+
return llvm::None;
706706

707707
// Read the header.
708708
auto Hdr = reinterpret_cast<const llvm::ELF::Elf64_Ehdr *>(Buf.get());
709709

710710
if (!Hdr->checkMagic())
711-
return false;
711+
return llvm::None;
712712

713713
// Check if we have a ELFCLASS32 or ELFCLASS64
714714
unsigned char FileClass = Hdr->getFileClass();
@@ -719,11 +719,11 @@ class ReflectionContext
719719
return readELFSections<ELFTraits<llvm::ELF::ELFCLASS32>>(
720720
ImageStart, FileBuffer, PotentialModuleNames);
721721
} else {
722-
return false;
722+
return llvm::None;
723723
}
724724
}
725725

726-
bool
726+
llvm::Optional<uint64_t>
727727
addImage(RemoteAddress ImageStart,
728728
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
729729
// Read the first few bytes to look for a magic header.
@@ -761,7 +761,7 @@ class ReflectionContext
761761
}
762762

763763
// We don't recognize the format.
764-
return false;
764+
return llvm::None;
765765
}
766766

767767
/// Adds an image using the FindSection closure to find the swift metadata
@@ -770,9 +770,9 @@ class ReflectionContext
770770
/// of freeing the memory buffer in the RemoteRef return value.
771771
/// process.
772772
/// \return
773-
/// \b True if any of the reflection sections were registered,
774-
/// \b false otherwise.
775-
bool
773+
/// \b The newly added reflection info ID if successful,
774+
/// \b llvm::None otherwise.
775+
llvm::Optional<uint64_t>
776776
addImage(llvm::function_ref<
777777
std::pair<RemoteRef<void>, uint64_t>(ReflectionSectionKind)>
778778
FindSection,
@@ -798,7 +798,7 @@ class ReflectionContext
798798

799799
// If we didn't find any sections, return.
800800
if (llvm::all_of(Pairs, [](const auto &Pair) { return !Pair.first; }))
801-
return false;
801+
return {};
802802

803803
ReflectionInfo Info = {{Pairs[0].first, Pairs[0].second},
804804
{Pairs[1].first, Pairs[1].second},
@@ -809,12 +809,11 @@ class ReflectionContext
809809
{Pairs[6].first, Pairs[6].second},
810810
{Pairs[7].first, Pairs[7].second},
811811
PotentialModuleNames};
812-
this->addReflectionInfo(Info);
813-
return true;
812+
return addReflectionInfo(Info);
814813
}
815814

816-
void addReflectionInfo(ReflectionInfo I) {
817-
getBuilder().addReflectionInfo(I);
815+
llvm::Optional<uint64_t> addReflectionInfo(ReflectionInfo I) {
816+
return getBuilder().addReflectionInfo(I);
818817
}
819818

820819
bool ownsObject(RemoteAddress ObjectAddress) {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#ifndef SWIFT_REFLECTION_TYPEREFBUILDER_H
1919
#define SWIFT_REFLECTION_TYPEREFBUILDER_H
2020

21+
#include "swift/Remote/ExternalTypeRefInfoProvider.h"
2122
#include "swift/Remote/MetadataReader.h"
2223
#include "swift/Reflection/MetadataSourceBuilder.h"
2324
#include "swift/Reflection/Records.h"
@@ -426,6 +427,8 @@ class TypeRefBuilder {
426427
TypeConverter TC;
427428
MetadataSourceBuilder MSB;
428429

430+
remote::ExternalTypeRefInfoProvider *ExternalProvider = nullptr;
431+
429432
#define TYPEREF(Id, Parent) \
430433
std::unordered_map<TypeRefID, const Id##TypeRef *, \
431434
TypeRefID::Hash, TypeRefID::Equal> Id##TypeRefs;
@@ -915,10 +918,13 @@ class TypeRefBuilder {
915918
/// Parsing reflection metadata
916919
///
917920

918-
void addReflectionInfo(ReflectionInfo I) {
921+
/// Add the ReflectionInfo and return a unique ID for the reflection image
922+
/// added. Since we only add reflection infos, the ID can be its index.
923+
llvm::Optional<uint64_t> addReflectionInfo(ReflectionInfo I) {
919924
ReflectionInfos.push_back(I);
925+
return ReflectionInfos.size() - 1;
920926
}
921-
927+
922928
const std::vector<ReflectionInfo> &getReflectionInfos() {
923929
return ReflectionInfos;
924930
}
@@ -943,6 +949,9 @@ class TypeRefBuilder {
943949
llvm::Optional<RemoteRef<FieldDescriptor>>
944950
findFieldDescriptorAtIndex(size_t Index, const std::string &MangledName);
945951

952+
llvm::Optional<RemoteRef<FieldDescriptor>>
953+
getFieldDescriptorFromProvider(const std::string &MangledName);
954+
946955
public:
947956
RemoteRef<char> readTypeRef(uint64_t remoteAddr);
948957

@@ -983,8 +992,9 @@ class TypeRefBuilder {
983992

984993
public:
985994
template<typename Runtime>
986-
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader)
987-
: TC(*this),
995+
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader,
996+
remote::ExternalTypeRefInfoProvider *provider = nullptr)
997+
: TC(*this), ExternalProvider(provider),
988998
PointerSize(sizeof(typename Runtime::StoredPointer)),
989999
TypeRefDemangler(
9901000
[this, &reader](RemoteRef<char> string, bool useOpaqueTypeSymbolicReferences) -> Demangle::Node * {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===--- ExternalTypeRefInfoProvider.h - Abstract access to external providers of typeref ------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file declares an abstract interface for external providers of typeref
14+
// information
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_REMOTE_EXTERNALTYPEREFINFOPROVIDER_H
19+
#define SWIFT_REMOTE_EXTERNALTYPEREFINFOPROVIDER_H
20+
21+
#include "llvm/ADT/ArrayRef.h"
22+
#include "llvm/ADT/StringRef.h"
23+
#include "llvm/ADT/Optional.h"
24+
25+
#include <string>
26+
27+
namespace swift {
28+
namespace reflection {
29+
30+
template <typename T>
31+
class ReflectionSection;
32+
class FieldDescriptorIterator;
33+
using FieldSection = ReflectionSection<FieldDescriptorIterator>;
34+
}
35+
36+
namespace remote {
37+
/// A struct with the information requited to locate a specific field
38+
/// descriptor.
39+
struct FieldDescriptorLocator {
40+
/// The reflection info ID the field descriptor belongs to.
41+
uint64_t InfoID;
42+
43+
/// The offset of the field descriptor in the FieldSection buffer.
44+
uint64_t Offset;
45+
};
46+
47+
/// An abstract interface for providing external type layout information.
48+
struct ExternalTypeRefInfoProvider {
49+
virtual ~ExternalTypeRefInfoProvider() = default;
50+
51+
/// Register the field descriptors of a reflection info with a given id with
52+
/// their corresponding mangled names. The amount of field descriptors and
53+
/// mangled names must be the same. If a field descriptor does not have a
54+
/// mangled name a corresponding empty string must be in the mangled_names
55+
/// array.
56+
virtual void registerFieldDescriptors(
57+
uint64_t InfoID,
58+
const swift::reflection::FieldSection &FieldDescriptors,
59+
const llvm::ArrayRef<std::string> &MangledNames) = 0;
60+
61+
/// Retrieve a pair representing the reflection info id and the offset of a
62+
/// field descriptor in the field section buffer, if available.
63+
virtual llvm::Optional<FieldDescriptorLocator>
64+
getFieldDescriptorLocator(const std::string &Name) = 0;
65+
66+
/// Returns whether looking for a mangled name in reflection info with a given
67+
/// id could possibly return information that couldn't be provided by the
68+
/// external provider.
69+
virtual bool shouldParseReflectionInfoWithId(uint64_t InfoID) = 0;
70+
};
71+
72+
} // namespace remote
73+
} // namespace swift
74+
#endif

0 commit comments

Comments
 (0)