@@ -1148,25 +1148,18 @@ class AccessorConformanceInfo : public ConformanceInfo {
1148
1148
}
1149
1149
};
1150
1150
1151
+ // / A base class for some code shared between fragile and resilient witness
1152
+ // / table layout.
1151
1153
class WitnessTableBuilderBase {
1152
1154
protected:
1153
1155
IRGenModule &IGM;
1154
1156
SILWitnessTable *SILWT;
1155
1157
CanType ConcreteType;
1156
1158
const RootProtocolConformance &Conformance;
1157
1159
const ProtocolConformance &ConformanceInContext;
1158
- ArrayRef<SILWitnessTable::Entry> SILEntries;
1159
- ArrayRef<SILWitnessTable::ConditionalConformance>
1160
- SILConditionalConformances;
1161
1160
1162
1161
Optional<FulfillmentMap> Fulfillments;
1163
1162
1164
- SmallVector<size_t , 4 > ConditionalRequirementPrivateDataIndices;
1165
-
1166
- // Conditional conformances and metadata caches are stored at negative
1167
- // offsets, with conditional conformances closest to 0.
1168
- unsigned NextPrivateDataIndex = 0 ;
1169
-
1170
1163
WitnessTableBuilderBase (IRGenModule &IGM, SILWitnessTable *SILWT)
1171
1164
: IGM(IGM), SILWT(SILWT),
1172
1165
ConcreteType (SILWT->getConformance ()->getDeclContext()
@@ -1176,21 +1169,7 @@ class AccessorConformanceInfo : public ConformanceInfo {
1176
1169
Conformance(*SILWT->getConformance ()),
1177
1170
ConformanceInContext(
1178
1171
mapConformanceIntoContext (IGM, Conformance,
1179
- Conformance.getDeclContext())),
1180
- SILEntries(SILWT->getEntries ()),
1181
- SILConditionalConformances(SILWT->getConditionalConformances ()) {}
1182
-
1183
- void addConditionalConformances () {
1184
- assert (NextPrivateDataIndex == 0 );
1185
- for (auto conditional : SILConditionalConformances) {
1186
- // We don't actually need to know anything about the specific
1187
- // conformances here, just make sure we get right private data slots.
1188
- (void )conditional;
1189
-
1190
- auto reqtIndex = getNextPrivateDataIndex ();
1191
- ConditionalRequirementPrivateDataIndices.push_back (reqtIndex);
1192
- }
1193
- }
1172
+ Conformance.getDeclContext())) {}
1194
1173
1195
1174
void defineAssociatedTypeWitnessTableAccessFunction (
1196
1175
AssociatedConformance requirement,
@@ -1202,11 +1181,6 @@ class AccessorConformanceInfo : public ConformanceInfo {
1202
1181
CanType associatedType,
1203
1182
ProtocolConformanceRef conformance);
1204
1183
1205
- // / Allocate another word of private data storage in the conformance table.
1206
- unsigned getNextPrivateDataIndex () {
1207
- return NextPrivateDataIndex++;
1208
- }
1209
-
1210
1184
const FulfillmentMap &getFulfillmentMap () {
1211
1185
if (Fulfillments) return *Fulfillments;
1212
1186
@@ -1239,39 +1213,52 @@ class AccessorConformanceInfo : public ConformanceInfo {
1239
1213
}
1240
1214
return *Fulfillments;
1241
1215
}
1242
-
1243
- // / The top-level entry point.
1244
- void build () {
1245
- addConditionalConformances ();
1246
- }
1247
-
1248
- public:
1249
- // / The number of private entries in the witness table.
1250
- unsigned getTablePrivateSize () const { return NextPrivateDataIndex; }
1251
1216
};
1252
1217
1253
- // / A class which lays out a specific conformance to a protocol.
1218
+ // / A fragile witness table is emitted to look like one in memory, except
1219
+ // / possibly with some blank slots which are filled in by an instantiation
1220
+ // / function.
1254
1221
class FragileWitnessTableBuilder : public WitnessTableBuilderBase ,
1255
1222
public SILWitnessVisitor<FragileWitnessTableBuilder> {
1256
1223
ConstantArrayBuilder &Table;
1257
1224
unsigned TableSize = ~0U ; // will get overwritten unconditionally
1258
1225
SmallVector<std::pair<size_t , const ConformanceInfo *>, 4 >
1259
1226
SpecializedBaseConformances;
1260
1227
1228
+ ArrayRef<SILWitnessTable::Entry> SILEntries;
1229
+ ArrayRef<SILWitnessTable::ConditionalConformance>
1230
+ SILConditionalConformances;
1231
+
1261
1232
const ProtocolInfo &PI;
1262
1233
1234
+ SmallVector<size_t , 4 > ConditionalRequirementPrivateDataIndices;
1235
+
1236
+ void addConditionalConformances () {
1237
+ for (auto reqtIndex : indices (SILConditionalConformances)) {
1238
+ // We don't actually need to know anything about the specific
1239
+ // conformances here, just make sure we get right private data slots.
1240
+ ConditionalRequirementPrivateDataIndices.push_back (reqtIndex);
1241
+ }
1242
+ }
1243
+
1263
1244
public:
1264
1245
FragileWitnessTableBuilder (IRGenModule &IGM, ConstantArrayBuilder &table,
1265
1246
SILWitnessTable *SILWT)
1266
1247
: WitnessTableBuilderBase(IGM, SILWT), Table(table),
1248
+ SILEntries (SILWT->getEntries ()),
1249
+ SILConditionalConformances(SILWT->getConditionalConformances ()),
1267
1250
PI(IGM.getProtocolInfo(SILWT->getConformance ()->getProtocol(),
1268
1251
ProtocolInfoKind::Full)) {}
1269
1252
1270
1253
// / The number of entries in the witness table.
1271
1254
unsigned getTableSize () const { return TableSize; }
1272
1255
1273
1256
// / The top-level entry point.
1274
- void build ();
1257
+ void build () {
1258
+ addConditionalConformances ();
1259
+ visitProtocolDecl (Conformance.getProtocol ());
1260
+ TableSize = Table.size ();
1261
+ }
1275
1262
1276
1263
// / Add reference to the protocol conformance descriptor that generated
1277
1264
// / this table.
@@ -1432,29 +1419,22 @@ class AccessorConformanceInfo : public ConformanceInfo {
1432
1419
llvm::Constant *buildInstantiationFunction ();
1433
1420
};
1434
1421
1422
+ // / A resilient witness table consists of a list of descriptor/witness pairs,
1423
+ // / and a runtime function builds the actual witness table in memory, placing
1424
+ // / entries in the correct oder and filling in default implementations as
1425
+ // / needed.
1435
1426
class ResilientWitnessTableBuilder : public WitnessTableBuilderBase {
1436
1427
public:
1437
1428
ResilientWitnessTableBuilder (IRGenModule &IGM, SILWitnessTable *SILWT)
1438
1429
: WitnessTableBuilderBase(IGM, SILWT) {}
1439
1430
1440
- void build () {
1441
- WitnessTableBuilderBase::build ();
1442
- }
1443
-
1444
1431
// / Collect the set of resilient witnesses, which will become part of the
1445
1432
// / protocol conformance descriptor.
1446
1433
void collectResilientWitnesses (
1447
1434
SmallVectorImpl<llvm::Constant *> &resilientWitnesses);
1448
1435
};
1449
1436
} // end anonymous namespace
1450
1437
1451
- // / Build the witness table.
1452
- void FragileWitnessTableBuilder::build () {
1453
- WitnessTableBuilderBase::build ();
1454
- visitProtocolDecl (Conformance.getProtocol ());
1455
- TableSize = Table.size ();
1456
- }
1457
-
1458
1438
llvm::Constant *IRGenModule::getAssociatedTypeWitness (Type type,
1459
1439
GenericSignature sig,
1460
1440
bool inProtocolContext) {
@@ -2148,7 +2128,6 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
2148
2128
PrettyStackTraceConformance _st (Context, " emitting witness table for" , conf);
2149
2129
2150
2130
unsigned tableSize = 0 ;
2151
- unsigned tablePrivateSize = 0 ;
2152
2131
llvm::GlobalVariable *global = nullptr ;
2153
2132
llvm::Constant *instantiationFunction = nullptr ;
2154
2133
bool isDependent = isDependentConformance (conf);
@@ -2174,23 +2153,18 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
2174
2153
llvm::MaybeAlign (getWitnessTableAlignment ().getValue ()));
2175
2154
2176
2155
tableSize = wtableBuilder.getTableSize ();
2177
- tablePrivateSize = wtableBuilder.getTablePrivateSize ();
2178
-
2179
2156
instantiationFunction = wtableBuilder.buildInstantiationFunction ();
2180
2157
} else {
2181
2158
// Build the witness table.
2182
2159
ResilientWitnessTableBuilder wtableBuilder (*this , wt);
2183
- wtableBuilder.build ();
2184
2160
2185
2161
// Collect the resilient witnesses to go into the conformance descriptor.
2186
2162
wtableBuilder.collectResilientWitnesses (resilientWitnesses);
2187
-
2188
- tableSize = 0 ;
2189
- tablePrivateSize = wtableBuilder.getTablePrivateSize ();
2190
2163
}
2191
2164
2192
2165
// Collect the information that will go into the protocol conformance
2193
2166
// descriptor.
2167
+ unsigned tablePrivateSize = wt->getConditionalConformances ().size ();
2194
2168
ConformanceDescription description (conf, wt, global, tableSize,
2195
2169
tablePrivateSize, isDependent);
2196
2170
0 commit comments