Skip to content

Commit 3eaf708

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 12b5008 commit 3eaf708

File tree

8 files changed

+240
-118
lines changed

8 files changed

+240
-118
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/ReflectionContext.h

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,8 @@ class ReflectionContext
887887
/// metadata as its isa pointer.
888888
const RecordTypeInfo *
889889
getMetadataTypeInfo(StoredPointer MetadataAddress,
890-
remote::TypeInfoProvider *ExternalTypeInfo) {
890+
remote::TypeInfoProvider *ExternalTypeInfo,
891+
ExternalDescriptorFinder *DF) {
891892
// See if we cached the layout already
892893
auto found = Cache.find(MetadataAddress);
893894
if (found != Cache.end())
@@ -904,12 +905,12 @@ class ReflectionContext
904905
case MetadataKind::Class: {
905906
// Figure out where the stored properties of this class begin
906907
// by looking at the size of the superclass
907-
auto start =
908-
this->readInstanceStartAndAlignmentFromClassMetadata(MetadataAddress);
908+
auto start = this->readInstanceStartAndAlignmentFromClassMetadata(
909+
MetadataAddress);
909910

910911
// Perform layout
911912
if (start)
912-
TI = TC.getClassInstanceTypeInfo(TR, *start, ExternalTypeInfo);
913+
TI = TC.getClassInstanceTypeInfo(TR, *start, ExternalTypeInfo, DF);
913914

914915
break;
915916
}
@@ -927,7 +928,8 @@ class ReflectionContext
927928
/// metadata as its isa pointer.
928929
const TypeInfo *
929930
getInstanceTypeInfo(StoredPointer ObjectAddress,
930-
remote::TypeInfoProvider *ExternalTypeInfo) {
931+
remote::TypeInfoProvider *ExternalTypeInfo,
932+
ExternalDescriptorFinder *DF) {
931933
auto MetadataAddress = readMetadataFromInstance(ObjectAddress);
932934
if (!MetadataAddress)
933935
return nullptr;
@@ -938,7 +940,7 @@ class ReflectionContext
938940

939941
switch (*kind) {
940942
case MetadataKind::Class:
941-
return getMetadataTypeInfo(*MetadataAddress, ExternalTypeInfo);
943+
return getMetadataTypeInfo(*MetadataAddress, ExternalTypeInfo, DF);
942944

943945
case MetadataKind::HeapLocalVariable: {
944946
auto CDAddr = this->readCaptureDescriptorFromMetadata(*MetadataAddress);
@@ -960,7 +962,7 @@ class ReflectionContext
960962

961963
auto Info = getBuilder().getClosureContextInfo(CD);
962964

963-
return getClosureContextInfo(ObjectAddress, Info, ExternalTypeInfo);
965+
return getClosureContextInfo(ObjectAddress, Info, ExternalTypeInfo, DF);
964966
}
965967

966968
case MetadataKind::HeapGenericLocalVariable: {
@@ -970,7 +972,7 @@ class ReflectionContext
970972
auto GenericHeapMeta =
971973
cast<TargetGenericBoxHeapMetadata<Runtime>>(Meta.getLocalBuffer());
972974
return getMetadataTypeInfo(GenericHeapMeta->BoxedType,
973-
ExternalTypeInfo);
975+
ExternalTypeInfo, DF);
974976
}
975977
return nullptr;
976978
}
@@ -1034,11 +1036,12 @@ class ReflectionContext
10341036
const TypeRef *ExistentialTR,
10351037
const TypeRef **OutInstanceTR,
10361038
RemoteAddress *OutInstanceAddress,
1037-
remote::TypeInfoProvider *ExternalTypeInfo) {
1039+
remote::TypeInfoProvider *ExternalTypeInfo,
1040+
ExternalDescriptorFinder *DF) {
10381041
if (ExistentialTR == nullptr)
10391042
return false;
10401043

1041-
auto ExistentialTI = getTypeInfo(ExistentialTR, ExternalTypeInfo);
1044+
auto ExistentialTI = getTypeInfo(ExistentialTR, ExternalTypeInfo, DF);
10421045
if (ExistentialTI == nullptr)
10431046
return false;
10441047

@@ -1121,7 +1124,8 @@ class ReflectionContext
11211124
return true;
11221125
};
11231126

1124-
auto ExistentialRecordTI = getRecordTypeInfo(&ExistentialTR, nullptr);
1127+
auto ExistentialRecordTI =
1128+
getRecordTypeInfo(&ExistentialTR, nullptr, nullptr);
11251129
if (!ExistentialRecordTI)
11261130
return {};
11271131

@@ -1173,12 +1177,13 @@ class ReflectionContext
11731177
/// if the compiler used a strategy we do not yet understand.
11741178
bool projectEnumValue(RemoteAddress EnumAddress, const TypeRef *EnumTR,
11751179
int *CaseIndex,
1176-
remote::TypeInfoProvider *ExternalTypeInfo) {
1180+
remote::TypeInfoProvider *ExternalTypeInfo,
1181+
ExternalDescriptorFinder *DF) {
11771182
// Get the TypeInfo and sanity-check it
11781183
if (EnumTR == nullptr) {
11791184
return false;
11801185
}
1181-
auto TI = getTypeInfo(EnumTR, ExternalTypeInfo);
1186+
auto TI = getTypeInfo(EnumTR, ExternalTypeInfo, DF);
11821187
if (TI == nullptr) {
11831188
return false;
11841189
}
@@ -1191,17 +1196,20 @@ class ReflectionContext
11911196

11921197
/// Return a description of the layout of a value with the given type.
11931198
const TypeInfo *getTypeInfo(const TypeRef *TR,
1194-
remote::TypeInfoProvider *ExternalTypeInfo) {
1199+
remote::TypeInfoProvider *ExternalTypeInfo,
1200+
ExternalDescriptorFinder *DF) {
11951201
if (TR == nullptr) {
11961202
return nullptr;
11971203
} else {
1198-
return getBuilder().getTypeConverter().getTypeInfo(TR, ExternalTypeInfo);
1204+
return getBuilder().getTypeConverter().getTypeInfo(TR, ExternalTypeInfo,
1205+
DF);
11991206
}
12001207
}
12011208

12021209
const RecordTypeInfo *getRecordTypeInfo(const TypeRef *TR,
1203-
remote::TypeInfoProvider *ExternalTypeInfo) {
1204-
auto *TypeInfo = getTypeInfo(TR, ExternalTypeInfo);
1210+
remote::TypeInfoProvider *ExternalTypeInfo,
1211+
ExternalDescriptorFinder *DF) {
1212+
auto *TypeInfo = getTypeInfo(TR, ExternalTypeInfo, DF);
12051213
return dyn_cast_or_null<const RecordTypeInfo>(TypeInfo);
12061214
}
12071215

@@ -1836,9 +1844,10 @@ class ReflectionContext
18361844

18371845
const TypeInfo *
18381846
getClosureContextInfo(StoredPointer Context, const ClosureContextInfo &Info,
1839-
remote::TypeInfoProvider *ExternalTypeInfo) {
1847+
remote::TypeInfoProvider *ExternalTypeInfo,
1848+
ExternalDescriptorFinder *DF) {
18401849
RecordTypeInfoBuilder Builder(getBuilder().getTypeConverter(),
1841-
RecordKind::ClosureContext);
1850+
RecordKind::ClosureContext, DF);
18421851

18431852
auto Metadata = readMetadataFromInstance(Context);
18441853
if (!Metadata)

include/swift/RemoteInspection/TypeLowering.h

Lines changed: 20 additions & 14 deletions
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()
@@ -356,7 +357,8 @@ class TypeConverter {
356357
const TypeInfo *EmptyTI = nullptr;
357358

358359
public:
359-
explicit TypeConverter(TypeRefBuilder &Builder) : Builder(Builder) {}
360+
explicit TypeConverter(TypeRefBuilder &Builder)
361+
: Builder(Builder) {}
360362

361363
TypeRefBuilder &getBuilder() { return Builder; }
362364

@@ -371,18 +373,20 @@ class TypeConverter {
371373
/// The type must either be concrete, or at least fixed-size, as
372374
/// determined by the isFixedSize() predicate.
373375
const TypeInfo *getTypeInfo(const TypeRef *TR,
374-
remote::TypeInfoProvider *externalInfo);
376+
remote::TypeInfoProvider *externalInfo,
377+
ExternalDescriptorFinder *DF);
375378

376379
/// Returns layout information for an instance of the given
377380
/// class.
378381
///
379382
/// Not cached.
380383
const RecordTypeInfo *
381384
getClassInstanceTypeInfo(const TypeRef *TR, unsigned start,
382-
remote::TypeInfoProvider *ExternalTypeInfo);
385+
remote::TypeInfoProvider *ExternalTypeInfo,
386+
ExternalDescriptorFinder *DF);
383387

384388
unsigned targetPointerSize() {
385-
auto *rawPointerTI = getTypeInfo(getRawPointerTypeRef(), nullptr);
389+
auto *rawPointerTI = getTypeInfo(getRawPointerTypeRef(), nullptr, nullptr);
386390
return rawPointerTI->getSize();
387391
}
388392

@@ -392,9 +396,9 @@ class TypeConverter {
392396
friend class swift::reflection::RecordTypeInfoBuilder;
393397
friend class swift::reflection::ExistentialTypeInfoBuilder;
394398

395-
const ReferenceTypeInfo *
396-
getReferenceTypeInfo(ReferenceKind Kind,
397-
ReferenceCounting Refcounting);
399+
const ReferenceTypeInfo *getReferenceTypeInfo(ReferenceKind Kind,
400+
ReferenceCounting Refcounting,
401+
ExternalDescriptorFinder *DF);
398402

399403
/// TypeRefs for special types for which we need to know the layout
400404
/// intrinsically in order to layout anything else.
@@ -407,9 +411,9 @@ class TypeConverter {
407411
const TypeRef *getThinFunctionTypeRef();
408412
const TypeRef *getAnyMetatypeTypeRef();
409413

410-
const TypeInfo *getThinFunctionTypeInfo();
411-
const TypeInfo *getThickFunctionTypeInfo();
412-
const TypeInfo *getAnyMetatypeTypeInfo();
414+
const TypeInfo *getThinFunctionTypeInfo(ExternalDescriptorFinder *DF);
415+
const TypeInfo *getThickFunctionTypeInfo(ExternalDescriptorFinder *DF);
416+
const TypeInfo *getAnyMetatypeTypeInfo(ExternalDescriptorFinder *DF);
413417
const TypeInfo *getEmptyTypeInfo();
414418

415419
template <typename TypeInfoTy, typename... Args>
@@ -424,6 +428,7 @@ class TypeConverter {
424428
/// tuples, structs, thick functions, etc.
425429
class RecordTypeInfoBuilder {
426430
TypeConverter &TC;
431+
ExternalDescriptorFinder *DF;
427432
unsigned Size, Alignment, NumExtraInhabitants;
428433
bool BitwiseTakable;
429434
RecordKind Kind;
@@ -432,9 +437,10 @@ class RecordTypeInfoBuilder {
432437
bool Invalid;
433438

434439
public:
435-
RecordTypeInfoBuilder(TypeConverter &TC, RecordKind Kind)
436-
: TC(TC), Size(0), Alignment(1), NumExtraInhabitants(0),
437-
BitwiseTakable(true), Kind(Kind), Empty(true), Invalid(false) {}
440+
RecordTypeInfoBuilder(TypeConverter &TC, RecordKind Kind,
441+
ExternalDescriptorFinder *DF)
442+
: TC(TC), DF(DF), Size(0), Alignment(1), NumExtraInhabitants(0),
443+
BitwiseTakable(true), Kind(Kind), Empty(true), Invalid(false) {}
438444

439445
bool isInvalid() const {
440446
return Invalid;

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 6 additions & 2 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"
@@ -1209,8 +1210,8 @@ class TypeRefBuilder {
12091210
remote::TypeInfoProvider *ExternalTypeInfo,
12101211
std::vector<FieldTypeInfo> &Fields);
12111212

1212-
/// Get the primitive type lowering for a builtin type.
1213-
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
1213+
std::unique_ptr<BuiltinTypeDescriptorInterface>
1214+
getBuiltinTypeInfoInterface(const TypeRef *TR, ExternalDescriptorFinder *DF);
12141215

12151216
/// Get the raw capture descriptor for a remote capture descriptor
12161217
/// address.
@@ -1223,6 +1224,9 @@ class TypeRefBuilder {
12231224
RemoteRef<MultiPayloadEnumDescriptor> getMultiPayloadEnumInfo(const TypeRef *TR);
12241225

12251226
private:
1227+
/// Get the primitive type lowering for a builtin type.
1228+
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
1229+
12261230
llvm::Optional<uint64_t> multiPayloadEnumPointerMask;
12271231

12281232
public:

0 commit comments

Comments
 (0)