Skip to content

Commit cdadaad

Browse files
committed
[Serialization] Push caching of deserialized types out of helper class
Decls need to do this to avoid re-entrancy issues, but it turns out types are simpler. I left a dummy "result" variable in the minimize churn, since I'm going to move all the cases into their own functions anyway.
1 parent 23fdccc commit cdadaad

File tree

1 file changed

+57
-60
lines changed

1 file changed

+57
-60
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 57 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4274,16 +4274,13 @@ Type ModuleFile::getType(TypeID TID) {
42744274
}
42754275

42764276
class swift::TypeDeserializer {
4277-
template <typename T>
4278-
using Serialized = ModuleFile::Serialized<T>;
42794277
using TypeID = serialization::TypeID;
42804278

42814279
ModuleFile &MF;
42824280
ASTContext &ctx;
4283-
Serialized<Type> &typeOrOffset;
42844281
public:
4285-
TypeDeserializer(ModuleFile &MF, Serialized<Type> &typeOrOffset)
4286-
: MF(MF), ctx(MF.getContext()), typeOrOffset(typeOrOffset) {}
4282+
explicit TypeDeserializer(ModuleFile &MF)
4283+
: MF(MF), ctx(MF.getContext()) {}
42874284

42884285
Expected<Type> getTypeCheckedImpl();
42894286
};
@@ -4300,7 +4297,24 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
43004297

43014298
BCOffsetRAII restoreOffset(DeclTypeCursor);
43024299
DeclTypeCursor.JumpToBit(typeOrOffset);
4303-
return TypeDeserializer(*this, typeOrOffset).getTypeCheckedImpl();
4300+
4301+
auto result = TypeDeserializer(*this).getTypeCheckedImpl();
4302+
if (!result)
4303+
return result;
4304+
typeOrOffset = result.get();
4305+
4306+
#ifndef NDEBUG
4307+
PrettyStackTraceType trace(getContext(), "deserializing", typeOrOffset.get());
4308+
if (typeOrOffset.get()->hasError()) {
4309+
typeOrOffset.get()->dump();
4310+
llvm_unreachable("deserialization produced an invalid type "
4311+
"(rdar://problem/30382791)");
4312+
}
4313+
#endif
4314+
4315+
// Invoke the callback on the deserialized type.
4316+
DeserializedTypeCallback(typeOrOffset.get());
4317+
return typeOrOffset.get();
43044318
}
43054319

43064320
Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
@@ -4319,6 +4333,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
43194333
StringRef blobData;
43204334
unsigned recordID = MF.DeclTypeCursor.readRecord(entry.ID, scratch,
43214335
&blobData);
4336+
Type result;
43224337

43234338
switch (recordID) {
43244339
case decls_block::BUILTIN_ALIAS_TYPE: {
@@ -4339,7 +4354,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
43394354
if (!alias ||
43404355
!alias->getDeclaredInterfaceType()->isEqual(expectedType.get())) {
43414356
// Fall back to the canonical type.
4342-
typeOrOffset = expectedType.get();
4357+
result = expectedType.get();
43434358
break;
43444359
}
43454360
}
@@ -4348,11 +4363,11 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
43484363
// Look through compatibility aliases that are now unavailable.
43494364
if (alias->getAttrs().isUnavailable(ctx) &&
43504365
alias->isCompatibilityAlias()) {
4351-
typeOrOffset = alias->getUnderlyingTypeLoc().getType();
4366+
result = alias->getUnderlyingTypeLoc().getType();
43524367
break;
43534368
}
43544369

4355-
typeOrOffset = alias->getDeclaredInterfaceType();
4370+
result = alias->getDeclaredInterfaceType();
43564371
break;
43574372
}
43584373

@@ -4404,7 +4419,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
44044419

44054420
auto parentTypeOrError = MF.getTypeChecked(parentTypeID);
44064421
if (!parentTypeOrError) {
4407-
typeOrOffset = underlyingType;
4422+
result = underlyingType;
44084423
break;
44094424
}
44104425

@@ -4414,17 +4429,17 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
44144429
alias->isCompatibilityAlias()) {
44154430
underlyingType = alias->getUnderlyingTypeLoc().getType().subst(subMap);
44164431
assert(underlyingType);
4417-
typeOrOffset = underlyingType;
4432+
result = underlyingType;
44184433
break;
44194434
}
44204435

44214436
if (!formSugaredType) {
4422-
typeOrOffset = underlyingType;
4437+
result = underlyingType;
44234438
break;
44244439
}
44254440

44264441
auto parentType = parentTypeOrError.get();
4427-
typeOrOffset = TypeAliasType::get(alias, parentType, subMap,
4442+
result = TypeAliasType::get(alias, parentType, subMap,
44284443
substitutedType);
44294444
break;
44304445
}
@@ -4474,9 +4489,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
44744489
return llvm::make_error<XRefError>("declaration is not a nominal type",
44754490
tinyTrace, fullName);
44764491
}
4477-
typeOrOffset = NominalType::get(nominal, parentTy.get(), ctx);
4478-
4479-
assert(typeOrOffset.isComplete());
4492+
result = NominalType::get(nominal, parentTy.get(), ctx);
44804493
break;
44814494
}
44824495

@@ -4488,7 +4501,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
44884501
if (!underlyingTy)
44894502
return underlyingTy.takeError();
44904503

4491-
typeOrOffset = ParenType::get(ctx, underlyingTy.get());
4504+
result = ParenType::get(ctx, underlyingTy.get());
44924505
break;
44934506
}
44944507

@@ -4517,7 +4530,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
45174530
elements.emplace_back(elementTy.get(), MF.getIdentifier(nameID));
45184531
}
45194532

4520-
typeOrOffset = TupleType::get(elements, ctx);
4533+
result = TupleType::get(elements, ctx);
45214534
break;
45224535
}
45234536

@@ -4594,10 +4607,10 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
45944607

45954608
if (recordID == decls_block::FUNCTION_TYPE) {
45964609
assert(genericSig == nullptr);
4597-
typeOrOffset = FunctionType::get(params, resultTy.get(), info);
4610+
result = FunctionType::get(params, resultTy.get(), info);
45984611
} else {
45994612
assert(genericSig != nullptr);
4600-
typeOrOffset = GenericFunctionType::get(genericSig,
4613+
result = GenericFunctionType::get(genericSig,
46014614
params, resultTy.get(), info);
46024615
}
46034616

@@ -4615,20 +4628,20 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
46154628

46164629
switch (repr) {
46174630
case serialization::MetatypeRepresentation::MR_None:
4618-
typeOrOffset = ExistentialMetatypeType::get(instanceType.get());
4631+
result = ExistentialMetatypeType::get(instanceType.get());
46194632
break;
46204633

46214634
case serialization::MetatypeRepresentation::MR_Thin:
46224635
MF.error();
46234636
break;
46244637

46254638
case serialization::MetatypeRepresentation::MR_Thick:
4626-
typeOrOffset = ExistentialMetatypeType::get(instanceType.get(),
4639+
result = ExistentialMetatypeType::get(instanceType.get(),
46274640
MetatypeRepresentation::Thick);
46284641
break;
46294642

46304643
case serialization::MetatypeRepresentation::MR_ObjC:
4631-
typeOrOffset = ExistentialMetatypeType::get(instanceType.get(),
4644+
result = ExistentialMetatypeType::get(instanceType.get(),
46324645
MetatypeRepresentation::ObjC);
46334646
break;
46344647

@@ -4650,21 +4663,21 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
46504663

46514664
switch (repr) {
46524665
case serialization::MetatypeRepresentation::MR_None:
4653-
typeOrOffset = MetatypeType::get(instanceType.get());
4666+
result = MetatypeType::get(instanceType.get());
46544667
break;
46554668

46564669
case serialization::MetatypeRepresentation::MR_Thin:
4657-
typeOrOffset = MetatypeType::get(instanceType.get(),
4670+
result = MetatypeType::get(instanceType.get(),
46584671
MetatypeRepresentation::Thin);
46594672
break;
46604673

46614674
case serialization::MetatypeRepresentation::MR_Thick:
4662-
typeOrOffset = MetatypeType::get(instanceType.get(),
4675+
result = MetatypeType::get(instanceType.get(),
46634676
MetatypeRepresentation::Thick);
46644677
break;
46654678

46664679
case serialization::MetatypeRepresentation::MR_ObjC:
4667-
typeOrOffset = MetatypeType::get(instanceType.get(),
4680+
result = MetatypeType::get(instanceType.get(),
46684681
MetatypeRepresentation::ObjC);
46694682
break;
46704683

@@ -4678,7 +4691,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
46784691
case decls_block::DYNAMIC_SELF_TYPE: {
46794692
TypeID selfID;
46804693
decls_block::DynamicSelfTypeLayout::readRecord(scratch, selfID);
4681-
typeOrOffset = DynamicSelfType::get(MF.getType(selfID), ctx);
4694+
result = DynamicSelfType::get(MF.getType(selfID), ctx);
46824695
break;
46834696
}
46844697

@@ -4699,7 +4712,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
46994712
if (!objectTy)
47004713
return objectTy.takeError();
47014714

4702-
typeOrOffset = ReferenceStorageType::get(objectTy.get(),
4715+
result = ReferenceStorageType::get(objectTy.get(),
47034716
ownership.getValue(), ctx);
47044717
break;
47054718
}
@@ -4719,7 +4732,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
47194732

47204733
Type interfaceType = GenericTypeParamType::get(depth, index, ctx);
47214734
Type contextType = env->mapTypeIntoContext(interfaceType);
4722-
typeOrOffset = contextType;
4735+
result = contextType;
47234736

47244737
if (contextType->hasError()) {
47254738
MF.error();
@@ -4735,7 +4748,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
47354748
decls_block::OpenedArchetypeTypeLayout::readRecord(scratch,
47364749
existentialID);
47374750

4738-
typeOrOffset = OpenedArchetypeType::get(MF.getType(existentialID));
4751+
result = OpenedArchetypeType::get(MF.getType(existentialID));
47394752
break;
47404753
}
47414754

@@ -4777,15 +4790,11 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
47774790
return nullptr;
47784791
}
47794792

4780-
// See if we triggered deserialization through our conformances.
4781-
if (typeOrOffset.isComplete())
4782-
break;
4783-
4784-
typeOrOffset = genericParam->getDeclaredInterfaceType();
4793+
result = genericParam->getDeclaredInterfaceType();
47854794
break;
47864795
}
47874796

4788-
typeOrOffset = GenericTypeParamType::get(declIDOrDepth,indexPlusOne-1,ctx);
4797+
result = GenericTypeParamType::get(declIDOrDepth,indexPlusOne-1,ctx);
47894798
break;
47904799
}
47914800

@@ -4804,7 +4813,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
48044813
protocols.push_back(protoTy.get());
48054814
}
48064815

4807-
typeOrOffset = ProtocolCompositionType::get(ctx, protocols,
4816+
result = ProtocolCompositionType::get(ctx, protocols,
48084817
hasExplicitAnyObject);
48094818
break;
48104819
}
@@ -4815,7 +4824,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
48154824

48164825
decls_block::DependentMemberTypeLayout::readRecord(scratch, baseID,
48174826
assocTypeID);
4818-
typeOrOffset = DependentMemberType::get(
4827+
result = DependentMemberType::get(
48194828
MF.getType(baseID),
48204829
cast<AssociatedTypeDecl>(MF.getDecl(assocTypeID)));
48214830
break;
@@ -4847,15 +4856,15 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
48474856
}
48484857

48494858
auto boundTy = BoundGenericType::get(nominal, parentTy, genericArgs);
4850-
typeOrOffset = boundTy;
4859+
result = boundTy;
48514860
break;
48524861
}
48534862

48544863
case decls_block::SIL_BLOCK_STORAGE_TYPE: {
48554864
TypeID captureID;
48564865

48574866
decls_block::SILBlockStorageTypeLayout::readRecord(scratch, captureID);
4858-
typeOrOffset = SILBlockStorageType::get(MF.getType(captureID)
4867+
result = SILBlockStorageType::get(MF.getType(captureID)
48594868
->getCanonicalType());
48604869
break;
48614870
}
@@ -4891,7 +4900,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
48914900
return nullptr;
48924901

48934902
auto subMap = MF.getSubstitutionMap(subMapID);
4894-
typeOrOffset = SILBoxType::get(ctx, layout, subMap);
4903+
result = SILBoxType::get(ctx, layout, subMap);
48954904
break;
48964905
}
48974906

@@ -5046,7 +5055,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
50465055

50475056
GenericSignature *genericSig = MF.getGenericSignature(rawGenericSig);
50485057

5049-
typeOrOffset = SILFunctionType::get(genericSig, extInfo,
5058+
result = SILFunctionType::get(genericSig, extInfo,
50505059
coroutineKind.getValue(),
50515060
calleeConvention.getValue(),
50525061
allParams, allYields, allResults,
@@ -5063,7 +5072,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
50635072
if (!baseTy)
50645073
return baseTy.takeError();
50655074

5066-
typeOrOffset = ArraySliceType::get(baseTy.get());
5075+
result = ArraySliceType::get(baseTy.get());
50675076
break;
50685077
}
50695078

@@ -5079,7 +5088,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
50795088
if (!valueTy)
50805089
return valueTy.takeError();
50815090

5082-
typeOrOffset = DictionaryType::get(keyTy.get(), valueTy.get());
5091+
result = DictionaryType::get(keyTy.get(), valueTy.get());
50835092
break;
50845093
}
50855094

@@ -5091,7 +5100,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
50915100
if (!baseTy)
50925101
return baseTy.takeError();
50935102

5094-
typeOrOffset = OptionalType::get(baseTy.get());
5103+
result = OptionalType::get(baseTy.get());
50955104
break;
50965105
}
50975106

@@ -5109,7 +5118,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
51095118
// FIXME: Check this?
51105119
auto parentTy = MF.getType(parentID);
51115120

5112-
typeOrOffset = UnboundGenericType::get(genericDecl, parentTy, ctx);
5121+
result = UnboundGenericType::get(genericDecl, parentTy, ctx);
51135122
break;
51145123
}
51155124

@@ -5119,19 +5128,7 @@ Expected<Type> TypeDeserializer::getTypeCheckedImpl() {
51195128
return nullptr;
51205129
}
51215130

5122-
#ifndef NDEBUG
5123-
PrettyStackTraceType trace(ctx, "deserializing", typeOrOffset.get());
5124-
if (typeOrOffset.get()->hasError()) {
5125-
typeOrOffset.get()->dump();
5126-
llvm_unreachable("deserialization produced an invalid type "
5127-
"(rdar://problem/30382791)");
5128-
}
5129-
#endif
5130-
5131-
// Invoke the callback on the deserialized type.
5132-
MF.DeserializedTypeCallback(typeOrOffset);
5133-
5134-
return typeOrOffset;
5131+
return result;
51355132
}
51365133

51375134
Decl *handleErrorAndSupplyMissingClassMember(ASTContext &context,

0 commit comments

Comments
 (0)