mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[serialization] Use canonical conformance records for substitutions...
...instead of keeping around extra deserialized copies. Also, fix memory management for inherited conformances already in the ASTContext, instead of just leaking them. In the long run, conformances under substitutions should be encoded with some kind of CONFORMANCE_REF, because it is known that these conformances will already exist. Swift SVN r6557
This commit is contained in:
@@ -458,12 +458,17 @@ MutableArrayRef<TypeLoc> ModuleFile::getTypes(ArrayRef<uint64_t> rawTypeIDs,
|
||||
///
|
||||
/// \sa processConformances
|
||||
template <typename T>
|
||||
ProtocolConformance *processConformance(ASTContext &ctx, T *decl, CanType canTy,
|
||||
ProtocolConformance *processConformance(ASTContext &ctx, T decl, CanType canTy,
|
||||
ProtocolDecl *proto,
|
||||
ProtocolConformance *conformance) {
|
||||
if (!conformance)
|
||||
return nullptr;
|
||||
|
||||
for (auto &inherited : conformance->InheritedMapping) {
|
||||
inherited.second = processConformance(ctx, decl, canTy, inherited.first,
|
||||
inherited.second);
|
||||
}
|
||||
|
||||
auto &conformanceRecord = ctx.ConformsTo[{canTy, proto}];
|
||||
|
||||
if (conformanceRecord && conformanceRecord != conformance) {
|
||||
@@ -473,12 +478,8 @@ ProtocolConformance *processConformance(ASTContext &ctx, T *decl, CanType canTy,
|
||||
conformanceRecord = conformance;
|
||||
}
|
||||
|
||||
ctx.recordConformance(proto, decl);
|
||||
|
||||
for (auto &inherited : conformance->InheritedMapping) {
|
||||
inherited.second = processConformance(ctx, decl, canTy, inherited.first,
|
||||
inherited.second);
|
||||
}
|
||||
if (decl)
|
||||
ctx.recordConformance(proto, decl);
|
||||
|
||||
return conformance;
|
||||
}
|
||||
@@ -1830,16 +1831,26 @@ Type ModuleFile::getType(TypeID TID) {
|
||||
archetypeID,
|
||||
replacementID);
|
||||
|
||||
SmallVector<ProtocolConformance *, 16> conformanceBuf;
|
||||
while (auto conformance = maybeReadConformance())
|
||||
conformanceBuf.push_back(conformance.getValue().second);
|
||||
|
||||
ArchetypeType *archetypeTy;
|
||||
Type replacementTy;
|
||||
{
|
||||
BCOffsetRAII restoreOffset(DeclTypeCursor);
|
||||
substitutions.push_back({getType(archetypeID)->castTo<ArchetypeType>(),
|
||||
getType(replacementID),
|
||||
ctx.AllocateCopy(conformanceBuf)});
|
||||
archetypeTy = getType(archetypeID)->castTo<ArchetypeType>();
|
||||
replacementTy = getType(replacementID);
|
||||
}
|
||||
|
||||
CanType canReplTy = replacementTy->getCanonicalType();
|
||||
|
||||
SmallVector<ProtocolConformance *, 16> conformanceBuf;
|
||||
while (auto conformancePair = maybeReadConformance()) {
|
||||
auto conformance = processConformance(ctx, nullptr, canReplTy,
|
||||
conformancePair->first,
|
||||
conformancePair->second);
|
||||
conformanceBuf.push_back(conformance);
|
||||
}
|
||||
|
||||
substitutions.push_back({archetypeTy, replacementTy,
|
||||
ctx.AllocateCopy(conformanceBuf)});
|
||||
}
|
||||
|
||||
boundTy->setSubstitutions(ctx.AllocateCopy(substitutions));
|
||||
|
||||
Reference in New Issue
Block a user