Skip to content

Commit 77b4b00

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 d976ea6 commit 77b4b00

File tree

5 files changed

+132
-31
lines changed

5 files changed

+132
-31
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
enum class FieldDescriptorKind : uint16_t;
24+
25+
/// A generic interface a builtin type descriptor.
26+
struct BuiltinTypeDescriptorInterface {
27+
const uint32_t Size;
28+
const uint32_t Alignment;
29+
const uint32_t Stride;
30+
const uint32_t NumExtraInhabitants;
31+
const bool IsBitwiseTakable;
32+
BuiltinTypeDescriptorInterface(uint32_t Size, uint32_t Alignment,
33+
uint32_t Stride, uint32_t NumExtraInhabitants,
34+
bool IsBitwiseTakable)
35+
: Size(Size), Alignment(Alignment), Stride(Stride),
36+
NumExtraInhabitants(NumExtraInhabitants),
37+
IsBitwiseTakable(IsBitwiseTakable) {}
38+
39+
virtual ~BuiltinTypeDescriptorInterface() {};
40+
41+
virtual bool hasMangledTypeName() = 0;
42+
virtual llvm::StringRef getMangledTypeName() = 0;
43+
virtual llvm::StringRef readMangledTypeName() = 0;
44+
};
45+
46+
// Interface for finding type descriptors that lives outside of reflection
47+
// metadata.
48+
struct ExternalDescriptorFinder {
49+
virtual ~ExternalDescriptorFinder(){};
50+
51+
virtual std::unique_ptr<BuiltinTypeDescriptorInterface>
52+
getBuiltinTypeInfoInterface(const TypeRef *TR) = 0;
53+
};
54+
55+
} // namespace reflection
56+
} // namespace swift
57+
#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: 12 additions & 5 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"
@@ -443,6 +444,8 @@ class TypeRefBuilder {
443444

444445
remote::ExternalTypeRefCache *ExternalTypeRefCache = nullptr;
445446

447+
ExternalDescriptorFinder *DF;
448+
446449
#define TYPEREF(Id, Parent) \
447450
std::unordered_map<TypeRefID, const Id##TypeRef *, \
448451
TypeRefID::Hash, TypeRefID::Equal> Id##TypeRefs;
@@ -1129,9 +1132,10 @@ class TypeRefBuilder {
11291132

11301133
public:
11311134
template<typename Runtime>
1132-
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader,
1133-
remote::ExternalTypeRefCache *externalCache = nullptr)
1134-
: TC(*this), ExternalTypeRefCache(externalCache),
1135+
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader,
1136+
remote::ExternalTypeRefCache *externalCache = nullptr,
1137+
ExternalDescriptorFinder *DF = nullptr)
1138+
: TC(*this), ExternalTypeRefCache(externalCache), DF(DF),
11351139
PointerSize(sizeof(typename Runtime::StoredPointer)),
11361140
TypeRefDemangler(
11371141
[this, &reader](RemoteRef<char> string, bool useOpaqueTypeSymbolicReferences) -> Demangle::Node * {
@@ -1209,8 +1213,8 @@ class TypeRefBuilder {
12091213
remote::TypeInfoProvider *ExternalTypeInfo,
12101214
std::vector<FieldTypeInfo> &Fields);
12111215

1212-
/// Get the primitive type lowering for a builtin type.
1213-
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
1216+
std::unique_ptr<BuiltinTypeDescriptorInterface>
1217+
getBuiltinTypeInfoInterface(const TypeRef *TR);
12141218

12151219
/// Get the raw capture descriptor for a remote capture descriptor
12161220
/// address.
@@ -1223,6 +1227,9 @@ class TypeRefBuilder {
12231227
RemoteRef<MultiPayloadEnumDescriptor> getMultiPayloadEnumInfo(const TypeRef *TR);
12241228

12251229
private:
1230+
/// Get the primitive type lowering for a builtin type.
1231+
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
1232+
12261233
llvm::Optional<uint64_t> multiPayloadEnumPointerMask;
12271234

12281235
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.getBuiltinTypeInfoInterface(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().getBuiltinTypeInfoInterface(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().getBuiltinTypeInfoInterface(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().getBuiltinTypeInfoInterface(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().getBuiltinTypeInfoInterface(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().getBuiltinTypeInfoInterface(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: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,45 @@ TypeRefBuilder::getBuiltinTypeInfo(const TypeRef *TR) {
460460
return nullptr;
461461
}
462462

463+
class BuiltinTypeDescriptorImpl : public BuiltinTypeDescriptorInterface {
464+
RemoteRef<BuiltinTypeDescriptor> BTD;
465+
TypeRefBuilder &Builder;
466+
467+
public:
468+
BuiltinTypeDescriptorImpl(RemoteRef<BuiltinTypeDescriptor> BTD,
469+
TypeRefBuilder &Builder)
470+
: BuiltinTypeDescriptorInterface(BTD->Size, BTD->getAlignment(),
471+
BTD->Stride, BTD->NumExtraInhabitants,
472+
BTD->isBitwiseTakable()),
473+
BTD(BTD), Builder(Builder) {}
474+
475+
~BuiltinTypeDescriptorImpl() override {}
476+
477+
bool hasMangledTypeName() override {
478+
return BTD->hasMangledTypeName();
479+
}
480+
481+
llvm::StringRef getMangledTypeName() override {
482+
return BTD->getMangledTypeName();
483+
}
484+
485+
StringRef readMangledTypeName() override {
486+
return Builder.getTypeRefString(Builder.readTypeRef(BTD, BTD->TypeName));
487+
};
488+
};
489+
490+
std::unique_ptr<BuiltinTypeDescriptorInterface>
491+
TypeRefBuilder::getBuiltinTypeInfoInterface(const TypeRef *TR) {
492+
if (DF)
493+
if (auto descriptor = DF->getBuiltinTypeInfoInterface(TR))
494+
return descriptor;
495+
496+
auto BTI = getBuiltinTypeInfo(TR);
497+
if (!BTI)
498+
return nullptr;
499+
return std::make_unique<BuiltinTypeDescriptorImpl>(BTI, *this);
500+
}
501+
463502
RemoteRef<MultiPayloadEnumDescriptor>
464503
TypeRefBuilder::getMultiPayloadEnumInfo(const TypeRef *TR) {
465504
std::string MangledName;

0 commit comments

Comments
 (0)