Skip to content

Commit 70c5755

Browse files
committed
[SR-381]: runtime resolution of type metadata from a name
replace ProtocolConformanceTypeKind with TypeMetadataRecordKind metadata reference does not need to be indirectable more efficient check for protocol conformances remove swift_getMangledTypeName(), not needed yet kill off Remangle.cpp for non-ObjC builds cleanup cleanup cleanup comments
1 parent 4991734 commit 70c5755

File tree

15 files changed

+691
-82
lines changed

15 files changed

+691
-82
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ enum : unsigned {
9393
NumGenericMetadataPrivateDataWords = 16,
9494
};
9595

96-
/// Kinds of protocol conformance record.
97-
enum class ProtocolConformanceTypeKind : unsigned {
96+
/// Kinds of type metadata/protocol conformance records.
97+
enum class TypeMetadataRecordKind : unsigned {
9898
/// The conformance is universal and might apply to any type.
9999
/// getDirectType() is nil.
100100
Universal,
@@ -130,7 +130,7 @@ enum class ProtocolConformanceTypeKind : unsigned {
130130
/// platforms, the class object always is the type metadata.
131131
UniqueDirectClass = 0xF,
132132
};
133-
133+
134134
/// Kinds of reference to protocol conformance.
135135
enum class ProtocolConformanceReferenceKind : unsigned {
136136
/// A direct reference to a protocol witness table.
@@ -139,32 +139,51 @@ enum class ProtocolConformanceReferenceKind : unsigned {
139139
/// table.
140140
WitnessTableAccessor,
141141
};
142-
143-
struct ProtocolConformanceFlags {
144-
private:
142+
143+
// Type metadata record discriminant
144+
struct TypeMetadataRecordFlags {
145+
protected:
145146
using int_type = unsigned;
146147
int_type Data;
147148

148149
enum : int_type {
149150
TypeKindMask = 0x0000000FU,
150151
TypeKindShift = 0,
151-
ConformanceKindMask = 0x00000010U,
152-
ConformanceKindShift = 4,
153152
};
154153

155154
public:
156-
constexpr ProtocolConformanceFlags() : Data(0) {}
157-
constexpr ProtocolConformanceFlags(int_type Data) : Data(Data) {}
155+
constexpr TypeMetadataRecordFlags() : Data(0) {}
156+
constexpr TypeMetadataRecordFlags(int_type Data) : Data(Data) {}
158157

159-
constexpr ProtocolConformanceTypeKind getTypeKind() const {
160-
return ProtocolConformanceTypeKind((Data >> TypeKindShift) & TypeKindMask);
158+
constexpr TypeMetadataRecordKind getTypeKind() const {
159+
return TypeMetadataRecordKind((Data >> TypeKindShift) & TypeKindMask);
160+
}
161+
constexpr TypeMetadataRecordFlags withTypeKind(
162+
TypeMetadataRecordKind ptk) const {
163+
return TypeMetadataRecordFlags(
164+
(Data & ~TypeKindMask) | (int_type(ptk) << TypeKindShift));
161165
}
166+
167+
int_type getValue() const { return Data; }
168+
};
169+
170+
// Protocol conformance discriminant
171+
struct ProtocolConformanceFlags : public TypeMetadataRecordFlags {
172+
private:
173+
enum : int_type {
174+
ConformanceKindMask = 0x00000010U,
175+
ConformanceKindShift = 4,
176+
};
177+
178+
public:
179+
constexpr ProtocolConformanceFlags() : TypeMetadataRecordFlags(0) {}
180+
constexpr ProtocolConformanceFlags(int_type Data) : TypeMetadataRecordFlags(Data) {}
181+
162182
constexpr ProtocolConformanceFlags withTypeKind(
163-
ProtocolConformanceTypeKind ptk) const {
183+
TypeMetadataRecordKind ptk) const {
164184
return ProtocolConformanceFlags(
165185
(Data & ~TypeKindMask) | (int_type(ptk) << TypeKindShift));
166186
}
167-
168187
constexpr ProtocolConformanceReferenceKind getConformanceKind() const {
169188
return ProtocolConformanceReferenceKind((Data >> ConformanceKindShift)
170189
& ConformanceKindMask);
@@ -174,8 +193,6 @@ struct ProtocolConformanceFlags {
174193
return ProtocolConformanceFlags(
175194
(Data & ~ConformanceKindMask) | (int_type(pck) << ConformanceKindShift));
176195
}
177-
178-
int_type getValue() const { return Data; }
179196
};
180197

181198
/// Flag that indicates whether an existential type is class-constrained or not.

include/swift/Runtime/Metadata.h

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,6 +2125,57 @@ struct GenericWitnessTable {
21252125
void *PrivateData[swift::NumGenericMetadataPrivateDataWords];
21262126
};
21272127

2128+
/// The structure of a type metadata record.
2129+
///
2130+
/// This contains enough static information to recover type metadata from a
2131+
/// name. It is only emitted for types that do not have an explicit protocol
2132+
/// conformance record.
2133+
///
2134+
/// This structure is notionally a subtype of a protocol conformance record
2135+
/// but as we cannot change the conformance record layout we have to make do
2136+
/// with some duplicated code.
2137+
struct TypeMetadataRecord {
2138+
private:
2139+
// Some description of the type that is resolvable at runtime.
2140+
union {
2141+
/// A direct reference to the metadata.
2142+
RelativeDirectPointer<Metadata> DirectType;
2143+
2144+
/// The generic metadata pattern for an unbound generic type.
2145+
RelativeDirectPointer<GenericMetadata> GenericPattern;
2146+
};
2147+
2148+
/// Flags describing the type metadata record.
2149+
TypeMetadataRecordFlags Flags;
2150+
2151+
public:
2152+
TypeMetadataRecordKind getTypeKind() const {
2153+
return Flags.getTypeKind();
2154+
}
2155+
2156+
const Metadata *getDirectType() const {
2157+
switch (Flags.getTypeKind()) {
2158+
case TypeMetadataRecordKind::Universal:
2159+
return nullptr;
2160+
2161+
case TypeMetadataRecordKind::UniqueDirectType:
2162+
case TypeMetadataRecordKind::NonuniqueDirectType:
2163+
case TypeMetadataRecordKind::UniqueDirectClass:
2164+
break;
2165+
2166+
case TypeMetadataRecordKind::UniqueIndirectClass:
2167+
case TypeMetadataRecordKind::UniqueGenericPattern:
2168+
assert(false && "not direct type metadata");
2169+
}
2170+
2171+
return DirectType;
2172+
}
2173+
2174+
/// Get the canonical metadata for the type referenced by this record, or
2175+
/// return null if the record references a generic or universal type.
2176+
const Metadata *getCanonicalTypeMetadata() const;
2177+
};
2178+
21282179
/// The structure of a protocol conformance record.
21292180
///
21302181
/// This contains enough static information to recover the witness table for a
@@ -2177,7 +2228,7 @@ struct ProtocolConformanceRecord {
21772228
return Flags;
21782229
}
21792230

2180-
ProtocolConformanceTypeKind getTypeKind() const {
2231+
TypeMetadataRecordKind getTypeKind() const {
21812232
return Flags.getTypeKind();
21822233
}
21832234
ProtocolConformanceReferenceKind getConformanceKind() const {
@@ -2186,16 +2237,16 @@ struct ProtocolConformanceRecord {
21862237

21872238
const Metadata *getDirectType() const {
21882239
switch (Flags.getTypeKind()) {
2189-
case ProtocolConformanceTypeKind::Universal:
2240+
case TypeMetadataRecordKind::Universal:
21902241
return nullptr;
21912242

2192-
case ProtocolConformanceTypeKind::UniqueDirectType:
2193-
case ProtocolConformanceTypeKind::NonuniqueDirectType:
2243+
case TypeMetadataRecordKind::UniqueDirectType:
2244+
case TypeMetadataRecordKind::NonuniqueDirectType:
21942245
break;
21952246

2196-
case ProtocolConformanceTypeKind::UniqueDirectClass:
2197-
case ProtocolConformanceTypeKind::UniqueIndirectClass:
2198-
case ProtocolConformanceTypeKind::UniqueGenericPattern:
2247+
case TypeMetadataRecordKind::UniqueDirectClass:
2248+
case TypeMetadataRecordKind::UniqueIndirectClass:
2249+
case TypeMetadataRecordKind::UniqueGenericPattern:
21992250
assert(false && "not direct type metadata");
22002251
}
22012252

@@ -2205,15 +2256,15 @@ struct ProtocolConformanceRecord {
22052256
// FIXME: This shouldn't exist
22062257
const ClassMetadata *getDirectClass() const {
22072258
switch (Flags.getTypeKind()) {
2208-
case ProtocolConformanceTypeKind::Universal:
2259+
case TypeMetadataRecordKind::Universal:
22092260
return nullptr;
2210-
case ProtocolConformanceTypeKind::UniqueDirectClass:
2261+
case TypeMetadataRecordKind::UniqueDirectClass:
22112262
break;
22122263

2213-
case ProtocolConformanceTypeKind::UniqueDirectType:
2214-
case ProtocolConformanceTypeKind::NonuniqueDirectType:
2215-
case ProtocolConformanceTypeKind::UniqueGenericPattern:
2216-
case ProtocolConformanceTypeKind::UniqueIndirectClass:
2264+
case TypeMetadataRecordKind::UniqueDirectType:
2265+
case TypeMetadataRecordKind::NonuniqueDirectType:
2266+
case TypeMetadataRecordKind::UniqueGenericPattern:
2267+
case TypeMetadataRecordKind::UniqueIndirectClass:
22172268
assert(false && "not direct class object");
22182269
}
22192270

@@ -2224,16 +2275,16 @@ struct ProtocolConformanceRecord {
22242275

22252276
const ClassMetadata * const *getIndirectClass() const {
22262277
switch (Flags.getTypeKind()) {
2227-
case ProtocolConformanceTypeKind::Universal:
2278+
case TypeMetadataRecordKind::Universal:
22282279
return nullptr;
22292280

2230-
case ProtocolConformanceTypeKind::UniqueIndirectClass:
2281+
case TypeMetadataRecordKind::UniqueIndirectClass:
22312282
break;
22322283

2233-
case ProtocolConformanceTypeKind::UniqueDirectType:
2234-
case ProtocolConformanceTypeKind::UniqueDirectClass:
2235-
case ProtocolConformanceTypeKind::NonuniqueDirectType:
2236-
case ProtocolConformanceTypeKind::UniqueGenericPattern:
2284+
case TypeMetadataRecordKind::UniqueDirectType:
2285+
case TypeMetadataRecordKind::UniqueDirectClass:
2286+
case TypeMetadataRecordKind::NonuniqueDirectType:
2287+
case TypeMetadataRecordKind::UniqueGenericPattern:
22372288
assert(false && "not indirect class object");
22382289
}
22392290

@@ -2242,16 +2293,16 @@ struct ProtocolConformanceRecord {
22422293

22432294
const GenericMetadata *getGenericPattern() const {
22442295
switch (Flags.getTypeKind()) {
2245-
case ProtocolConformanceTypeKind::Universal:
2296+
case TypeMetadataRecordKind::Universal:
22462297
return nullptr;
22472298

2248-
case ProtocolConformanceTypeKind::UniqueGenericPattern:
2299+
case TypeMetadataRecordKind::UniqueGenericPattern:
22492300
break;
22502301

2251-
case ProtocolConformanceTypeKind::UniqueDirectClass:
2252-
case ProtocolConformanceTypeKind::UniqueIndirectClass:
2253-
case ProtocolConformanceTypeKind::UniqueDirectType:
2254-
case ProtocolConformanceTypeKind::NonuniqueDirectType:
2302+
case TypeMetadataRecordKind::UniqueDirectClass:
2303+
case TypeMetadataRecordKind::UniqueIndirectClass:
2304+
case TypeMetadataRecordKind::UniqueDirectType:
2305+
case TypeMetadataRecordKind::NonuniqueDirectType:
22552306
assert(false && "not generic metadata pattern");
22562307
}
22572308

@@ -2817,7 +2868,12 @@ const WitnessTable *swift_conformsToProtocol(const Metadata *type,
28172868
extern "C"
28182869
void swift_registerProtocolConformances(const ProtocolConformanceRecord *begin,
28192870
const ProtocolConformanceRecord *end);
2820-
2871+
2872+
/// Register a block of type metadata records dynamic lookup.
2873+
extern "C"
2874+
void swift_registerTypeMetadataRecords(const TypeMetadataRecord *begin,
2875+
const TypeMetadataRecord *end);
2876+
28212877
/// Return the type name for a given type metadata.
28222878
std::string nameForMetadata(const Metadata *type,
28232879
bool qualified = true);

0 commit comments

Comments
 (0)