Runtime/IRGen: Two-phase metadata initialization for resilient classes

Similar to the non-resilient case, except we also emit a 'relocation
function'. The class descriptor now contains this relocation function
if the class has resilient ancestry, and the relocation function
calls the runtime's swift_relocateClassMetadata() entry point.

The metadata completion function calls swift_initClassMetadata() and
does layout, just like the non-resilient case.

Fixes <rdar://problem/40810002>.
This commit is contained in:
Slava Pestov
2018-08-15 03:37:29 -07:00
parent c71f1e422b
commit 6150e34508
8 changed files with 221 additions and 200 deletions

View File

@@ -3555,16 +3555,36 @@ IRGenModule::getAddrOfTypeMetadataInstantiationFunction(NominalTypeDecl *D,
return entry;
}
llvm::Type *argTys[] = {
/// Type descriptor.
TypeContextDescriptorPtrTy,
/// Generic arguments.
Int8PtrPtrTy,
/// Generic metadata pattern.
Int8PtrPtrTy
};
auto fnType = llvm::FunctionType::get(TypeMetadataPtrTy,
argTys, /*isVarArg*/ false);
// This function is used in two cases -- allocating generic type metadata,
// and relocating non-generic resilient class metadata.
llvm::FunctionType *fnType;
if (D->isGenericContext()) {
// MetadataInstantiator in ABI/Metadata.h
llvm::Type *argTys[] = {
/// Type descriptor.
TypeContextDescriptorPtrTy,
/// Generic arguments.
Int8PtrPtrTy,
/// Generic metadata pattern.
Int8PtrPtrTy
};
fnType = llvm::FunctionType::get(TypeMetadataPtrTy, argTys,
/*isVarArg*/ false);
} else {
assert(isa<ClassDecl>(D));
// MetadataRelocator in ABI/Metadata.h
llvm::Type *argTys[] = {
/// Type descriptor.
TypeContextDescriptorPtrTy,
};
fnType = llvm::FunctionType::get(TypeMetadataPtrTy, argTys,
/*isVarArg*/ false);
}
Signature signature(fnType, llvm::AttributeList(), DefaultCC);
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, signature);