Skip to content

Commit 3793b29

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 3793b29

File tree

6 files changed

+148
-43
lines changed

6 files changed

+148
-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: 30 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,11 @@ 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+
DescriptorFinder *DF;
414+
415+
#define TYPEREF(Id, Parent) \
416+
std::unordered_map<TypeRefID, const Id##TypeRef *, \
417+
TypeRefID::Hash, TypeRefID::Equal> Id##TypeRefs;
416418
#include "swift/RemoteInspection/TypeRefs.def"
417419

418420
public:
@@ -453,7 +455,10 @@ class TypeRefBuilder {
453455
}
454456
};
455457

456-
struct ReflectionTypeDescriptorFinder {
458+
/// The default descriptor finder implementation that find descriptors from
459+
/// reflection metadata.
460+
struct ReflectionTypeDescriptorFinder
461+
: public swift::reflection::DescriptorFinder {
457462
ReflectionTypeDescriptorFinder(TypeRefBuilder &Builder,
458463
remote::ExternalTypeRefCache *externalCache)
459464
: Builder(Builder), ExternalTypeRefCache(externalCache) {}
@@ -476,8 +481,8 @@ class TypeRefBuilder {
476481
/// Load unsubstituted field types for a nominal type.
477482
RemoteRef<FieldDescriptor> getFieldTypeInfo(const TypeRef *TR);
478483

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

482487
/// Get the raw capture descriptor for a remote capture descriptor
483488
/// address.
@@ -506,7 +511,11 @@ class TypeRefBuilder {
506511
llvm::Optional<std::string> normalizeReflectionName(RemoteRef<char> name);
507512

508513
private:
514+
/// Get the primitive type lowering for a builtin type.
515+
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
516+
509517
void populateFieldTypeInfoCacheWithReflectionAtIndex(size_t Index);
518+
510519
llvm::Optional<RemoteRef<FieldDescriptor>>
511520
findFieldDescriptorAtIndex(size_t Index, const std::string &MangledName);
512521

@@ -548,6 +557,8 @@ class TypeRefBuilder {
548557

549558
TypeRefBuilder &Builder;
550559

560+
/// The external typeref cache for looking up field descriptor locators in
561+
/// an external file.
551562
remote::ExternalTypeRefCache *ExternalTypeRefCache = nullptr;
552563

553564
public:
@@ -844,7 +855,6 @@ class TypeRefBuilder {
844855

845856
BuiltTypeDecl createTypeDecl(std::string &&mangledName, bool &typeAlias) {
846857
return {{(mangledName)}};
847-
;
848858
}
849859

850860
BuiltProtocolDecl createProtocolDecl(Node *node) {
@@ -1409,6 +1419,7 @@ class TypeRefBuilder {
14091419
using IntVariableReader =
14101420
std::function<llvm::Optional<uint64_t>(std::string, unsigned)>;
14111421

1422+
/// The type descriptor finder that looks up descriptors from metadata.
14121423
ReflectionTypeDescriptorFinder RDF;
14131424

14141425
// These fields are captured from the MetadataReader template passed into the
@@ -1428,8 +1439,9 @@ class TypeRefBuilder {
14281439
public:
14291440
template <typename Runtime>
14301441
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader,
1431-
remote::ExternalTypeRefCache *externalCache = nullptr)
1432-
: TC(*this), RDF(*this, externalCache),
1442+
remote::ExternalTypeRefCache *externalCache = nullptr,
1443+
DescriptorFinder *descriptorFinder = nullptr)
1444+
: TC(*this), DF(descriptorFinder), RDF(*this, externalCache),
14331445
PointerSize(sizeof(typename Runtime::StoredPointer)),
14341446
TypeRefDemangler([this, &reader](RemoteRef<char> string,
14351447
bool useOpaqueTypeSymbolicReferences)
@@ -1519,10 +1531,11 @@ class TypeRefBuilder {
15191531
remote::TypeInfoProvider *ExternalTypeInfo,
15201532
std::vector<FieldTypeInfo> &Fields);
15211533

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

15271540
/// Get the raw capture descriptor for a remote capture descriptor
15281541
/// address.
@@ -1542,6 +1555,9 @@ class TypeRefBuilder {
15421555
}
15431556

15441557
private:
1558+
/// Get the primitive type lowering for a builtin type.
1559+
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
1560+
15451561
llvm::Optional<uint64_t> multiPayloadEnumPointerMask;
15461562

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

stdlib/public/RemoteInspection/TypeRefBuilder.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,42 @@ TypeRefBuilder::ReflectionTypeDescriptorFinder::getBuiltinTypeInfo(
471471
return nullptr;
472472
}
473473

474+
class BuiltinTypeDescriptorImpl : public BuiltinTypeDescriptorBase {
475+
RemoteRef<BuiltinTypeDescriptor> BTD;
476+
TypeRefBuilder &Builder;
477+
478+
public:
479+
BuiltinTypeDescriptorImpl(RemoteRef<BuiltinTypeDescriptor> BTD,
480+
TypeRefBuilder &Builder)
481+
: BuiltinTypeDescriptorBase(BTD->Size, BTD->getAlignment(),
482+
BTD->Stride, BTD->NumExtraInhabitants,
483+
BTD->isBitwiseTakable()),
484+
BTD(BTD), Builder(Builder) {}
485+
486+
~BuiltinTypeDescriptorImpl() override {}
487+
488+
StringRef getMangledTypeName() override {
489+
return Builder.getTypeRefString(Builder.readTypeRef(BTD, BTD->TypeName));
490+
};
491+
};
492+
493+
std::unique_ptr<BuiltinTypeDescriptorBase>
494+
TypeRefBuilder::ReflectionTypeDescriptorFinder::getBuiltinTypeDescriptor(
495+
const TypeRef *TR) {
496+
if (auto BTI = getBuiltinTypeInfo(TR))
497+
return std::make_unique<BuiltinTypeDescriptorImpl>(BTI, Builder);
498+
return nullptr;
499+
}
500+
501+
std::unique_ptr<BuiltinTypeDescriptorBase>
502+
TypeRefBuilder::getBuiltinTypeDescriptor(const TypeRef *TR) {
503+
if (DF)
504+
if (auto descriptor = DF->getBuiltinTypeDescriptor(TR))
505+
return descriptor;
506+
507+
return RDF.getBuiltinTypeDescriptor(TR);
508+
}
509+
474510
RemoteRef<MultiPayloadEnumDescriptor>
475511
TypeRefBuilder::ReflectionTypeDescriptorFinder::getMultiPayloadEnumInfo(
476512
const TypeRef *TR) {

0 commit comments

Comments
 (0)