Skip to content

Commit 0c212b3

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 0c212b3

File tree

5 files changed

+139
-39
lines changed

5 files changed

+139
-39
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===--------------- ExternalDescriptorFinder.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_EXTERNAL_DESCRIPTOR_FINDER_H
14+
#define SWIFT_REFLECTION_EXTERNAL_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 BuiltinTypeDescriptorInterface {
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+
BuiltinTypeDescriptorInterface(uint32_t Size, uint32_t Alignment,
32+
uint32_t Stride, uint32_t NumExtraInhabitants,
33+
bool IsBitwiseTakable)
34+
: Size(Size), Alignment(Alignment), Stride(Stride),
35+
NumExtraInhabitants(NumExtraInhabitants),
36+
IsBitwiseTakable(IsBitwiseTakable) {}
37+
38+
virtual ~BuiltinTypeDescriptorInterface() {};
39+
40+
virtual llvm::StringRef readMangledTypeName() = 0;
41+
};
42+
43+
/// Interface for finding type descriptors. Implementors may provide descriptors
44+
/// that live inside or outside reflection metadata.
45+
struct ExternalDescriptorFinder {
46+
virtual ~ExternalDescriptorFinder(){};
47+
48+
virtual std::unique_ptr<BuiltinTypeDescriptorInterface>
49+
getBuiltinTypeDescriptor(const TypeRef *TR) = 0;
50+
};
51+
52+
} // namespace reflection
53+
} // namespace swift
54+
#endif

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/ExternalDescriptorFinder.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+
BuiltinTypeDescriptorInterface *descriptor);
178179

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

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 25 additions & 13 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/ExternalDescriptorFinder.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+
ExternalDescriptorFinder *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,8 @@ class TypeRefBuilder {
453455
}
454456
};
455457

456-
struct ReflectionTypeDescriptorFinder {
458+
struct ReflectionTypeDescriptorFinder
459+
: public swift::reflection::ExternalDescriptorFinder {
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<BuiltinTypeDescriptorInterface>
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

@@ -1428,8 +1435,9 @@ class TypeRefBuilder {
14281435
public:
14291436
template <typename Runtime>
14301437
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader,
1431-
remote::ExternalTypeRefCache *externalCache = nullptr)
1432-
: TC(*this), RDF(*this, externalCache),
1438+
remote::ExternalTypeRefCache *externalCache = nullptr,
1439+
ExternalDescriptorFinder *DF = nullptr)
1440+
: TC(*this), DF(DF), RDF(*this, externalCache),
14331441
PointerSize(sizeof(typename Runtime::StoredPointer)),
14341442
TypeRefDemangler([this, &reader](RemoteRef<char> string,
14351443
bool useOpaqueTypeSymbolicReferences)
@@ -1519,10 +1527,11 @@ class TypeRefBuilder {
15191527
remote::TypeInfoProvider *ExternalTypeInfo,
15201528
std::vector<FieldTypeInfo> &Fields);
15211529

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

15271536
/// Get the raw capture descriptor for a remote capture descriptor
15281537
/// address.
@@ -1542,6 +1551,9 @@ class TypeRefBuilder {
15421551
}
15431552

15441553
private:
1554+
/// Get the primitive type lowering for a builtin type.
1555+
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
1556+
15451557
llvm::Optional<uint64_t> multiPayloadEnumPointerMask;
15461558

15471559
public:

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 22 additions & 25 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,
233+
BuiltinTypeDescriptorInterface *descriptor)
234+
: TypeInfo(TypeInfoKind::Builtin, descriptor->Size,
235+
descriptor->Alignment, descriptor->Stride,
238236
descriptor->NumExtraInhabitants,
239-
descriptor->isBitwiseTakable()),
240-
Name(builder.getTypeRefString(
241-
builder.readTypeRef(descriptor, descriptor->TypeName)))
242-
{}
237+
descriptor->IsBitwiseTakable),
238+
Name(descriptor->readMangledTypeName()) {}
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 BuiltinTypeDescriptorInterface {
475+
RemoteRef<BuiltinTypeDescriptor> BTD;
476+
TypeRefBuilder &Builder;
477+
478+
public:
479+
BuiltinTypeDescriptorImpl(RemoteRef<BuiltinTypeDescriptor> BTD,
480+
TypeRefBuilder &Builder)
481+
: BuiltinTypeDescriptorInterface(BTD->Size, BTD->getAlignment(),
482+
BTD->Stride, BTD->NumExtraInhabitants,
483+
BTD->isBitwiseTakable()),
484+
BTD(BTD), Builder(Builder) {}
485+
486+
~BuiltinTypeDescriptorImpl() override {}
487+
488+
StringRef readMangledTypeName() override {
489+
return Builder.getTypeRefString(Builder.readTypeRef(BTD, BTD->TypeName));
490+
};
491+
};
492+
493+
std::unique_ptr<BuiltinTypeDescriptorInterface>
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<BuiltinTypeDescriptorInterface>
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)