@@ -980,19 +980,6 @@ bool irgen::isDependentConformance(const NormalProtocolConformance *conformance)
980
980
conformance, [](unsigned , CanType, ProtocolDecl *) { return true ; });
981
981
}
982
982
983
- // / Detail about how an object conforms to a protocol.
984
- class irgen ::ConformanceInfo {
985
- friend ProtocolInfo;
986
- public:
987
- virtual ~ConformanceInfo () {}
988
- virtual llvm::Value *getTable (IRGenFunction &IGF,
989
- llvm::Value **conformingMetadataCache) const = 0;
990
- // / Try to get this table as a constant pointer. This might just
991
- // / not be supportable at all.
992
- virtual llvm::Constant *tryGetConstantTable (IRGenModule &IGM,
993
- CanType conformingType) const = 0;
994
- };
995
-
996
983
static llvm::Value *
997
984
emitConditionalConformancesBuffer (IRGenFunction &IGF,
998
985
const ProtocolConformance *conformance) {
@@ -1268,13 +1255,10 @@ llvm::Value *uniqueForeignWitnessTableRef(IRGenFunction &IGF,
1268
1255
1269
1256
// TODO: Use the witness entry instead of falling through here.
1270
1257
1271
- // Look for a protocol type info.
1272
- const ProtocolInfo &basePI = IGM.getProtocolInfo (baseProto);
1258
+ // Look for conformance info.
1273
1259
auto *astConf = ConformanceInContext.getInheritedConformance (baseProto);
1274
1260
assert (astConf->getType ()->isEqual (ConcreteType));
1275
-
1276
- const ConformanceInfo &conf =
1277
- basePI.getConformance (IGM, baseProto, astConf);
1261
+ const ConformanceInfo &conf = IGM.getConformanceInfo (baseProto, astConf);
1278
1262
1279
1263
// If we can emit the base witness table as a constant, do so.
1280
1264
llvm::Constant *baseWitness = conf.tryGetConstantTable (IGM, ConcreteType);
@@ -1649,10 +1633,8 @@ getAssociatedTypeWitnessTableAccessFunction(AssociatedConformance requirement,
1649
1633
if (associatedConformance.isConcrete ()) {
1650
1634
assert (associatedType->isEqual (associatedConformance.getConcrete ()->getType ()));
1651
1635
1652
- const ProtocolInfo &protocolI = IGM.getProtocolInfo (associatedProtocol);
1653
- conformanceI =
1654
- &protocolI.getConformance (IGM, associatedProtocol,
1655
- associatedConformance.getConcrete ());
1636
+ conformanceI = &IGM.getConformanceInfo (associatedProtocol,
1637
+ associatedConformance.getConcrete ());
1656
1638
1657
1639
// If we can emit a constant table, do so.
1658
1640
// In principle, any time we can do this, we should try to re-use this
@@ -2131,53 +2113,54 @@ ProtocolInfo *ProtocolInfo::create(ArrayRef<WitnessTableEntry> table) {
2131
2113
return new (buffer) ProtocolInfo (table);
2132
2114
}
2133
2115
2134
- ProtocolInfo::~ProtocolInfo () {
2135
- for (auto &conf : Conformances) {
2136
- delete conf.second ;
2137
- }
2138
- }
2116
+ // Provide a unique home for the ConformanceInfo vtable.
2117
+ void ConformanceInfo::anchor () {}
2139
2118
2140
2119
// / Find the conformance information for a protocol.
2141
2120
const ConformanceInfo &
2142
- ProtocolInfo::getConformance (IRGenModule &IGM, ProtocolDecl *protocol,
2143
- const ProtocolConformance *conformance) const {
2121
+ IRGenModule::getConformanceInfo ( const ProtocolDecl *protocol,
2122
+ const ProtocolConformance *conformance) {
2144
2123
assert (conformance->getProtocol () == protocol &&
2145
2124
" conformance is for wrong protocol" );
2146
2125
2147
2126
auto checkCache =
2148
- [& ](const ProtocolConformance *conf) -> Optional< ConformanceInfo *> {
2127
+ [this ](const ProtocolConformance *conf) -> const ConformanceInfo * {
2149
2128
// Check whether we've already cached this.
2150
2129
auto it = Conformances.find (conf);
2151
2130
if (it != Conformances.end ())
2152
- return it->second ;
2131
+ return it->second . get () ;
2153
2132
2154
- return None ;
2133
+ return nullptr ;
2155
2134
};
2156
2135
2157
2136
if (auto found = checkCache (conformance))
2158
- return ** found;
2137
+ return *found;
2159
2138
2160
2139
// Drill down to the root normal
2161
2140
auto normalConformance = conformance->getRootNormalConformance ();
2162
2141
2163
- ConformanceInfo *info;
2142
+ const ConformanceInfo *info;
2164
2143
// If the conformance is dependent in any way, we need to unique it.
2165
2144
// TODO: maybe this should apply whenever it's out of the module?
2166
2145
// TODO: actually enable this
2146
+ // FIXME: Both implementations of ConformanceInfo are trivially-destructible,
2147
+ // so in theory we could allocate them on a BumpPtrAllocator. But there's not
2148
+ // a good one for us to use. (The ASTContext's outlives the IRGenModule in
2149
+ // batch mode.)
2167
2150
if (isDependentConformance (normalConformance) ||
2168
2151
// Foreign types need to go through the accessor to unique the witness
2169
2152
// table.
2170
2153
normalConformance->isSynthesizedNonUnique ()) {
2171
2154
info = new AccessorConformanceInfo (conformance);
2172
- Conformances.insert ({ conformance, info} );
2155
+ Conformances.try_emplace ( conformance, info);
2173
2156
} else {
2174
2157
// Otherwise, we can use a direct-referencing conformance, which can get
2175
2158
// away with the non-specialized conformance.
2176
2159
if (auto found = checkCache (normalConformance))
2177
- return ** found;
2160
+ return *found;
2178
2161
2179
2162
info = new DirectConformanceInfo (normalConformance);
2180
- Conformances.insert ({ normalConformance, info} );
2163
+ Conformances.try_emplace ( normalConformance, info);
2181
2164
}
2182
2165
2183
2166
return *info;
@@ -2835,9 +2818,7 @@ llvm::Value *irgen::emitWitnessTableRef(IRGenFunction &IGF,
2835
2818
LocalTypeDataKind::forConcreteProtocolWitnessTable (concreteConformance));
2836
2819
if (wtable) return wtable;
2837
2820
2838
- auto &protoI = IGF.IGM .getProtocolInfo (proto);
2839
- auto &conformanceI =
2840
- protoI.getConformance (IGF.IGM , proto, concreteConformance);
2821
+ auto &conformanceI = IGF.IGM .getConformanceInfo (proto, concreteConformance);
2841
2822
wtable = conformanceI.getTable (IGF, srcMetadataCache);
2842
2823
2843
2824
IGF.setScopedLocalTypeData (
0 commit comments