Skip to content

Commit f09f518

Browse files
committed
Add interface for lookup up of externally stored type descriptors
Currently, TypeRefBuilder knows how to parse type descriptors from reflection metadata. We aim to store the same information that lives in type descriptors externally, as an effort to support embedded Swift debugging. In order to take advantage of all of the existing type information parsing code that exists today in remote mirrors, add an interface for external lookup of type descriptors, and replace all the usages of type descriptors with their generic counterpart (this patch only adds support for builtin descriptors, but follow up patches will add support for other descriptor types).
1 parent 6663dc0 commit f09f518

File tree

6 files changed

+160
-43
lines changed

6 files changed

+160
-43
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===--------------- DescriptorFinder.h -------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 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+
#ifndef SWIFT_REFLECTION_DESCRIPTOR_FINDER_H
14+
#define SWIFT_REFLECTION_DESCRIPTOR_FINDER_H
15+
16+
#include "llvm/ADT/StringRef.h"
17+
18+
namespace swift {
19+
namespace reflection {
20+
21+
class TypeRef;
22+
23+
/// An abstract interface for a builtin type descriptor.
24+
struct BuiltinTypeDescriptorBase {
25+
const uint32_t Size;
26+
const uint32_t Alignment;
27+
const uint32_t Stride;
28+
const uint32_t NumExtraInhabitants;
29+
const bool IsBitwiseTakable;
30+
31+
BuiltinTypeDescriptorBase(uint32_t Size, uint32_t Alignment, uint32_t Stride,
32+
uint32_t NumExtraInhabitants, bool IsBitwiseTakable)
33+
: Size(Size), Alignment(Alignment), Stride(Stride),
34+
NumExtraInhabitants(NumExtraInhabitants),
35+
IsBitwiseTakable(IsBitwiseTakable) {}
36+
37+
virtual ~BuiltinTypeDescriptorBase(){};
38+
39+
virtual llvm::StringRef getMangledTypeName() = 0;
40+
};
41+
42+
/// Interface for finding type descriptors. Implementors may provide descriptors
43+
/// that live inside or outside reflection metadata.
44+
struct DescriptorFinder {
45+
virtual ~DescriptorFinder(){};
46+
47+
virtual std::unique_ptr<BuiltinTypeDescriptorBase>
48+
getBuiltinTypeDescriptor(const TypeRef *TR) = 0;
49+
};
50+
51+
} // namespace reflection
52+
} // namespace swift
53+
#endif

include/swift/RemoteInspection/ReflectionContext.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/Concurrency/Actor.h"
3131
#include "swift/Remote/MemoryReader.h"
3232
#include "swift/Remote/MetadataReader.h"
33+
#include "swift/RemoteInspection/DescriptorFinder.h"
3334
#include "swift/RemoteInspection/GenericMetadataCacheEntry.h"
3435
#include "swift/RemoteInspection/Records.h"
3536
#include "swift/RemoteInspection/RuntimeInternals.h"
@@ -214,8 +215,9 @@ class ReflectionContext
214215

215216
explicit ReflectionContext(
216217
std::shared_ptr<MemoryReader> reader,
217-
remote::ExternalTypeRefCache *externalCache = nullptr)
218-
: super(std::move(reader), *this, externalCache) {}
218+
remote::ExternalTypeRefCache *externalCache = nullptr,
219+
reflection::DescriptorFinder *descriptorFinder = nullptr)
220+
: super(std::move(reader), *this, externalCache, descriptorFinder) {}
219221

220222
ReflectionContext(const ReflectionContext &other) = delete;
221223
ReflectionContext &operator=(const ReflectionContext &other) = delete;

include/swift/RemoteInspection/TypeLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/Support/Casting.h"
2424
#include "swift/Remote/MetadataReader.h"
2525
#include "swift/Remote/TypeInfoProvider.h"
26+
#include "swift/RemoteInspection/DescriptorFinder.h"
2627

2728
#include <memory>
2829

@@ -174,7 +175,7 @@ class BuiltinTypeInfo : public TypeInfo {
174175

175176
public:
176177
explicit BuiltinTypeInfo(TypeRefBuilder &builder,
177-
RemoteRef<BuiltinTypeDescriptor> descriptor);
178+
BuiltinTypeDescriptorBase &descriptor);
178179

179180
/// Construct an empty builtin type info.
180181
BuiltinTypeInfo()

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "swift/Remote/ExternalTypeRefCache.h"
2222
#include "swift/Remote/MetadataReader.h"
23+
#include "swift/RemoteInspection/DescriptorFinder.h"
2324
#include "swift/RemoteInspection/MetadataSourceBuilder.h"
2425
#include "swift/RemoteInspection/Records.h"
2526
#include "swift/RemoteInspection/TypeLowering.h"
@@ -409,10 +410,9 @@ class TypeRefBuilder {
409410

410411
TypeConverter TC;
411412

412-
#define TYPEREF(Id, Parent) \
413-
std::unordered_map<TypeRefID, const Id##TypeRef *, TypeRefID::Hash, \
414-
TypeRefID::Equal> \
415-
Id##TypeRefs;
413+
#define TYPEREF(Id, Parent) \
414+
std::unordered_map<TypeRefID, const Id##TypeRef *, \
415+
TypeRefID::Hash, TypeRefID::Equal> Id##TypeRefs;
416416
#include "swift/RemoteInspection/TypeRefs.def"
417417

418418
public:
@@ -453,7 +453,10 @@ class TypeRefBuilder {
453453
}
454454
};
455455

456-
struct ReflectionTypeDescriptorFinder {
456+
/// The default descriptor finder implementation that find descriptors from
457+
/// reflection metadata.
458+
struct ReflectionTypeDescriptorFinder
459+
: public swift::reflection::DescriptorFinder {
457460
ReflectionTypeDescriptorFinder(TypeRefBuilder &Builder,
458461
remote::ExternalTypeRefCache *externalCache)
459462
: Builder(Builder), ExternalTypeRefCache(externalCache) {}
@@ -476,8 +479,8 @@ class TypeRefBuilder {
476479
/// Load unsubstituted field types for a nominal type.
477480
RemoteRef<FieldDescriptor> getFieldTypeInfo(const TypeRef *TR);
478481

479-
/// Get the primitive type lowering for a builtin type.
480-
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
482+
std::unique_ptr<BuiltinTypeDescriptorBase>
483+
getBuiltinTypeDescriptor(const TypeRef *TR) override;
481484

482485
/// Get the raw capture descriptor for a remote capture descriptor
483486
/// address.
@@ -506,7 +509,11 @@ class TypeRefBuilder {
506509
llvm::Optional<std::string> normalizeReflectionName(RemoteRef<char> name);
507510

508511
private:
512+
/// Get the primitive type lowering for a builtin type.
513+
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
514+
509515
void populateFieldTypeInfoCacheWithReflectionAtIndex(size_t Index);
516+
510517
llvm::Optional<RemoteRef<FieldDescriptor>>
511518
findFieldDescriptorAtIndex(size_t Index, const std::string &MangledName);
512519

@@ -548,6 +555,8 @@ class TypeRefBuilder {
548555

549556
TypeRefBuilder &Builder;
550557

558+
/// The external typeref cache for looking up field descriptor locators in
559+
/// an external file.
551560
remote::ExternalTypeRefCache *ExternalTypeRefCache = nullptr;
552561

553562
public:
@@ -844,7 +853,6 @@ class TypeRefBuilder {
844853

845854
BuiltTypeDecl createTypeDecl(std::string &&mangledName, bool &typeAlias) {
846855
return {{(mangledName)}};
847-
;
848856
}
849857

850858
BuiltProtocolDecl createProtocolDecl(Node *node) {
@@ -1409,8 +1417,21 @@ class TypeRefBuilder {
14091417
using IntVariableReader =
14101418
std::function<llvm::Optional<uint64_t>(std::string, unsigned)>;
14111419

1420+
/// The external type descriptor finder injected into this TypeRefBuilder, for
1421+
/// lookup of descriptors outside of metadata.
1422+
DescriptorFinder *EDF;
1423+
1424+
/// The type descriptor finder that looks up descriptors from metadata.
14121425
ReflectionTypeDescriptorFinder RDF;
14131426

1427+
/// Returns the descriptor finders in the order that they should be consulted
1428+
/// in.
1429+
llvm::SmallVector<DescriptorFinder *, 2> getDescriptorFinders() {
1430+
if (EDF)
1431+
return {EDF, &RDF};
1432+
return {&RDF};
1433+
}
1434+
14141435
// These fields are captured from the MetadataReader template passed into the
14151436
// TypeRefBuilder struct, to isolate its template-ness from the rest of
14161437
// TypeRefBuilder.
@@ -1428,8 +1449,9 @@ class TypeRefBuilder {
14281449
public:
14291450
template <typename Runtime>
14301451
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader,
1431-
remote::ExternalTypeRefCache *externalCache = nullptr)
1432-
: TC(*this), RDF(*this, externalCache),
1452+
remote::ExternalTypeRefCache *externalCache = nullptr,
1453+
DescriptorFinder *externalDescriptorFinder = nullptr)
1454+
: TC(*this), EDF(externalDescriptorFinder), RDF(*this, externalCache),
14331455
PointerSize(sizeof(typename Runtime::StoredPointer)),
14341456
TypeRefDemangler([this, &reader](RemoteRef<char> string,
14351457
bool useOpaqueTypeSymbolicReferences)
@@ -1519,10 +1541,11 @@ class TypeRefBuilder {
15191541
remote::TypeInfoProvider *ExternalTypeInfo,
15201542
std::vector<FieldTypeInfo> &Fields);
15211543

1522-
/// Get the primitive type lowering for a builtin type.
1523-
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR) {
1524-
return RDF.getBuiltinTypeInfo(TR);
1525-
}
1544+
/// Get the generic interface version of a builtin type descriptor. This
1545+
/// descriptor may originate from reflection metadata or from an external
1546+
/// source.
1547+
std::unique_ptr<BuiltinTypeDescriptorBase>
1548+
getBuiltinTypeDescriptor(const TypeRef *TR);
15261549

15271550
/// Get the raw capture descriptor for a remote capture descriptor
15281551
/// address.
@@ -1542,6 +1565,9 @@ class TypeRefBuilder {
15421565
}
15431566

15441567
private:
1568+
/// Get the primitive type lowering for a builtin type.
1569+
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
1570+
15451571
llvm::Optional<uint64_t> multiPayloadEnumPointerMask;
15461572

15471573
public:

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -230,16 +230,12 @@ void TypeInfo::dump(std::ostream &stream, unsigned Indent) const {
230230
}
231231

232232
BuiltinTypeInfo::BuiltinTypeInfo(TypeRefBuilder &builder,
233-
RemoteRef<BuiltinTypeDescriptor> descriptor)
234-
: TypeInfo(TypeInfoKind::Builtin,
235-
descriptor->Size,
236-
descriptor->getAlignment(),
237-
descriptor->Stride,
238-
descriptor->NumExtraInhabitants,
239-
descriptor->isBitwiseTakable()),
240-
Name(builder.getTypeRefString(
241-
builder.readTypeRef(descriptor, descriptor->TypeName)))
242-
{}
233+
BuiltinTypeDescriptorBase &descriptor)
234+
: TypeInfo(TypeInfoKind::Builtin, descriptor.Size,
235+
descriptor.Alignment, descriptor.Stride,
236+
descriptor.NumExtraInhabitants,
237+
descriptor.IsBitwiseTakable),
238+
Name(descriptor.getMangledTypeName()) {}
243239

244240
bool BuiltinTypeInfo::readExtraInhabitantIndex(
245241
remote::MemoryReader &reader, remote::RemoteAddress address,
@@ -1641,9 +1637,8 @@ const RecordTypeInfo *RecordTypeInfoBuilder::build() {
16411637
Kind, Fields);
16421638
}
16431639

1644-
const ReferenceTypeInfo *
1645-
TypeConverter::getReferenceTypeInfo(ReferenceKind Kind,
1646-
ReferenceCounting Refcounting) {
1640+
const ReferenceTypeInfo *TypeConverter::getReferenceTypeInfo(
1641+
ReferenceKind Kind, ReferenceCounting Refcounting) {
16471642
auto key = std::make_pair(unsigned(Kind), unsigned(Refcounting));
16481643
auto found = ReferenceCache.find(key);
16491644
if (found != ReferenceCache.end())
@@ -1664,7 +1659,7 @@ TypeConverter::getReferenceTypeInfo(ReferenceKind Kind,
16641659
//
16651660
// Weak references do not have any extra inhabitants.
16661661

1667-
auto BuiltinTI = Builder.getBuiltinTypeInfo(TR);
1662+
auto BuiltinTI = Builder.getBuiltinTypeDescriptor(TR);
16681663
if (BuiltinTI == nullptr) {
16691664
DEBUG_LOG(fprintf(stderr, "No TypeInfo for reference type: "); TR->dump());
16701665
return nullptr;
@@ -1689,7 +1684,7 @@ TypeConverter::getReferenceTypeInfo(ReferenceKind Kind,
16891684
}
16901685

16911686
auto *TI = makeTypeInfo<ReferenceTypeInfo>(BuiltinTI->Size,
1692-
BuiltinTI->getAlignment(),
1687+
BuiltinTI->Alignment,
16931688
BuiltinTI->Stride,
16941689
numExtraInhabitants,
16951690
bitwiseTakable,
@@ -1705,13 +1700,14 @@ TypeConverter::getThinFunctionTypeInfo() {
17051700
if (ThinFunctionTI != nullptr)
17061701
return ThinFunctionTI;
17071702

1708-
auto descriptor = getBuilder().getBuiltinTypeInfo(getThinFunctionTypeRef());
1703+
auto descriptor =
1704+
getBuilder().getBuiltinTypeDescriptor(getThinFunctionTypeRef());
17091705
if (descriptor == nullptr) {
17101706
DEBUG_LOG(fprintf(stderr, "No TypeInfo for function type\n"));
17111707
return nullptr;
17121708
}
17131709

1714-
ThinFunctionTI = makeTypeInfo<BuiltinTypeInfo>(getBuilder(), descriptor);
1710+
ThinFunctionTI = makeTypeInfo<BuiltinTypeInfo>(getBuilder(), *descriptor.get());
17151711

17161712
return ThinFunctionTI;
17171713
}
@@ -1739,13 +1735,14 @@ TypeConverter::getAnyMetatypeTypeInfo() {
17391735
if (AnyMetatypeTI != nullptr)
17401736
return AnyMetatypeTI;
17411737

1742-
auto descriptor = getBuilder().getBuiltinTypeInfo(getAnyMetatypeTypeRef());
1738+
auto descriptor =
1739+
getBuilder().getBuiltinTypeDescriptor(getAnyMetatypeTypeRef());
17431740
if (descriptor == nullptr) {
17441741
DEBUG_LOG(fprintf(stderr, "No TypeInfo for metatype type\n"));
17451742
return nullptr;
17461743
}
17471744

1748-
AnyMetatypeTI = makeTypeInfo<BuiltinTypeInfo>(getBuilder(), descriptor);
1745+
AnyMetatypeTI = makeTypeInfo<BuiltinTypeInfo>(getBuilder(), *descriptor.get());
17491746

17501747
return AnyMetatypeTI;
17511748
}
@@ -2245,7 +2242,7 @@ class EnumTypeInfoBuilder {
22452242

22462243
// Do we have a fixed layout?
22472244
// TODO: Test whether a missing FixedDescriptor is actually relevant.
2248-
auto FixedDescriptor = TC.getBuilder().getBuiltinTypeInfo(TR);
2245+
auto FixedDescriptor = TC.getBuilder().getBuiltinTypeDescriptor(TR);
22492246
if (!FixedDescriptor || GenericPayloadCases > 0) {
22502247
// This is a "dynamic multi-payload enum". For example,
22512248
// this occurs with:
@@ -2283,9 +2280,9 @@ class EnumTypeInfoBuilder {
22832280
// * Has at least two cases with non-zero payload size
22842281
// * Has a descriptor stored as BuiltinTypeInfo
22852282
Size = FixedDescriptor->Size;
2286-
Alignment = FixedDescriptor->getAlignment();
2283+
Alignment = FixedDescriptor->Alignment;
22872284
NumExtraInhabitants = FixedDescriptor->NumExtraInhabitants;
2288-
BitwiseTakable = FixedDescriptor->isBitwiseTakable();
2285+
BitwiseTakable = FixedDescriptor->IsBitwiseTakable;
22892286
unsigned Stride = ((Size + Alignment - 1) & ~(Alignment - 1));
22902287
if (Stride == 0)
22912288
Stride = 1;
@@ -2395,12 +2392,12 @@ class LowerType
23952392

23962393
/// Otherwise, get the fixed layout information from reflection
23972394
/// metadata.
2398-
auto descriptor = TC.getBuilder().getBuiltinTypeInfo(B);
2395+
auto descriptor = TC.getBuilder().getBuiltinTypeDescriptor(B);
23992396
if (descriptor == nullptr) {
24002397
DEBUG_LOG(fprintf(stderr, "No TypeInfo for builtin type: "); B->dump());
24012398
return nullptr;
24022399
}
2403-
return TC.makeTypeInfo<BuiltinTypeInfo>(TC.getBuilder(), descriptor);
2400+
return TC.makeTypeInfo<BuiltinTypeInfo>(TC.getBuilder(), *descriptor.get());
24042401
}
24052402

24062403
const TypeInfo *visitAnyNominalTypeRef(const TypeRef *TR) {
@@ -2424,15 +2421,15 @@ class LowerType
24242421
// descriptor to see if we at least know its size
24252422
// and alignment.
24262423
if (auto ImportedTypeDescriptor =
2427-
TC.getBuilder().getBuiltinTypeInfo(TR)) {
2424+
TC.getBuilder().getBuiltinTypeDescriptor(TR)) {
24282425
// This might be an external type we treat as opaque (like C structs),
24292426
// the external type info provider might have better type information,
24302427
// so ask it first.
24312428
if (auto External = QueryExternalTypeInfoProvider())
24322429
return External;
24332430

24342431
return TC.makeTypeInfo<BuiltinTypeInfo>(TC.getBuilder(),
2435-
ImportedTypeDescriptor);
2432+
*ImportedTypeDescriptor.get());
24362433
}
24372434

24382435
if (FD == nullptr) {

0 commit comments

Comments
 (0)