Merge pull request #18893 from slavapestov/resilient-class-pattern
Use a true-const pattern to initialize non-generic resilient class metadata
diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h
index bd2fc60..51ed926 100644
--- a/include/swift/ABI/Metadata.h
+++ b/include/swift/ABI/Metadata.h
@@ -3085,7 +3085,7 @@
}
};
-/// An instantiation pattern for class metadata.
+/// An instantiation pattern for generic class metadata.
template <typename Runtime>
struct TargetGenericClassMetadataPattern final :
TargetGenericMetadataPattern<Runtime>,
@@ -3138,7 +3138,7 @@
using GenericClassMetadataPattern =
TargetGenericClassMetadataPattern<InProcess>;
-/// An instantiation pattern for value metadata.
+/// An instantiation pattern for generic value metadata.
template <typename Runtime>
struct TargetGenericValueMetadataPattern final :
TargetGenericMetadataPattern<Runtime>,
@@ -3316,10 +3316,43 @@
using InPlaceValueMetadataCache =
TargetInPlaceValueMetadataCache<InProcess>;
+template <typename Runtime>
+struct TargetResilientClassMetadataPattern;
+
/// An instantiation pattern for non-generic resilient class metadata.
/// Used in conjunction with InPlaceValueMetadataInitialization.
using MetadataRelocator =
- Metadata *(const TargetTypeContextDescriptor<InProcess> *description);
+ Metadata *(const TargetTypeContextDescriptor<InProcess> *type,
+ const TargetResilientClassMetadataPattern<InProcess> *pattern);
+
+/// An instantiation pattern for non-generic resilient class metadata.
+template <typename Runtime>
+struct TargetResilientClassMetadataPattern {
+ /// If the class descriptor's hasResilientSuperclass() flag is set,
+ /// this field instead points at a function that allocates metadata
+ /// with the correct size at runtime.
+ TargetRelativeDirectPointer<Runtime, MetadataRelocator> RelocationFunction;
+
+ /// The heap-destructor function.
+ TargetRelativeDirectPointer<Runtime, HeapObjectDestroyer> Destroy;
+
+ /// The ivar-destructor function.
+ TargetRelativeDirectPointer<Runtime, ClassIVarDestroyer> IVarDestroyer;
+
+ /// The class flags.
+ ClassFlags Flags;
+
+ // The following fields are only present in ObjC interop.
+
+ /// Our ClassROData.
+ TargetRelativeDirectPointer<Runtime, void> Data;
+
+ /// Our metaclass.
+ TargetRelativeDirectPointer<Runtime, TargetAnyClassMetadata<Runtime>> Metaclass;
+};
+
+using ResilientClassMetadataPattern =
+ TargetResilientClassMetadataPattern<InProcess>;
/// The control structure for performing non-trivial initialization of
/// singleton value metadata, which is required when e.g. a non-generic
@@ -3340,8 +3373,8 @@
/// If the class descriptor's hasResilientSuperclass() flag is set,
/// this field instead points at a function that allocates metadata
/// with the correct size at runtime.
- TargetRelativeDirectPointer<Runtime, MetadataRelocator>
- RelocationFunction;
+ TargetRelativeDirectPointer<Runtime, TargetResilientClassMetadataPattern<Runtime>>
+ ResilientPattern;
};
/// The completion function. The pattern will always be null.
@@ -3358,8 +3391,10 @@
TargetMetadata<Runtime> *allocate(
const TargetTypeContextDescriptor<Runtime> *description) const {
- if (hasRelocationFunction(description))
- return RelocationFunction(description);
+ if (hasRelocationFunction(description)) {
+ return ResilientPattern->RelocationFunction(description,
+ ResilientPattern.get());
+ }
return IncompleteMetadata.get();
}
};
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index 177ef2f..13580c3 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -574,15 +574,13 @@
const TypeLayout * const *fieldTypes,
uint32_t *fieldOffsets);
-/// Relocate the metadata for a class and copy fields from the given template.
-/// The final size of the metadata is calculated at runtime from the size of
-/// the superclass metadata together with the given number of immediate
-/// members.
+/// Allocate the metadata for a class and copy fields from the given pattern.
+/// The final size of the metadata is calculated at runtime from the metadata
+/// bounds in the class descriptor.
SWIFT_RUNTIME_EXPORT
ClassMetadata *
swift_relocateClassMetadata(ClassDescriptor *descriptor,
- ClassMetadata *pattern,
- size_t patternSize);
+ ResilientClassMetadataPattern *pattern);
/// Initialize the field offset vector for a dependent-layout class, using the
/// "Universal" layout strategy.
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index 70dcc95..b9db24ba 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -670,19 +670,19 @@
// Metadata *swift_allocateGenericClassMetadata(ClassDescriptor *type,
// const void * const *arguments,
-// const void * const *template);
+// const void *template);
FUNCTION(AllocateGenericClassMetadata, swift_allocateGenericClassMetadata,
C_CC, RETURNS(TypeMetadataPtrTy),
- ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrPtrTy),
+ ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrTy),
ATTRS(NoUnwind))
// Metadata *swift_allocateGenericValueMetadata(ValueTypeDescriptor *type,
// const void * const *arguments,
-// const void * const *template,
+// const void *template,
// size_t extraSize);
FUNCTION(AllocateGenericValueMetadata, swift_allocateGenericValueMetadata,
C_CC, RETURNS(TypeMetadataPtrTy),
- ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrPtrTy, SizeTy),
+ ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrTy, SizeTy),
ATTRS(NoUnwind))
// MetadataResponse swift_checkMetadataState(MetadataRequest request,
@@ -809,12 +809,11 @@
ATTRS(NoUnwind, ReadOnly))
// Metadata *swift_relocateClassMetadata(TypeContextDescriptor *descriptor,
-// Metadata *pattern,
-// size_t patternSize);
+// const void *pattern);
FUNCTION(RelocateClassMetadata,
swift_relocateClassMetadata, C_CC,
RETURNS(TypeMetadataPtrTy),
- ARGS(TypeContextDescriptorPtrTy, TypeMetadataPtrTy, SizeTy),
+ ARGS(TypeContextDescriptorPtrTy, Int8PtrTy),
ATTRS(NoUnwind))
// struct FieldInfo { size_t Size; size_t AlignMask; };
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 8d620e9..efcff0d 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -3282,8 +3282,9 @@
assert(init);
if (isPattern) {
+ assert(isConstant && "Type metadata patterns must be constant");
auto addr = getAddrOfTypeMetadataPattern(concreteType->getAnyNominal(),
- isConstant, init, section);
+ init, section);
return cast<llvm::GlobalValue>(addr);
}
@@ -3488,12 +3489,11 @@
llvm::Constant *
IRGenModule::getAddrOfTypeMetadataPattern(NominalTypeDecl *D) {
- return getAddrOfTypeMetadataPattern(D, false, ConstantInit(), "");
+ return getAddrOfTypeMetadataPattern(D, ConstantInit(), "");
}
llvm::Constant *
IRGenModule::getAddrOfTypeMetadataPattern(NominalTypeDecl *D,
- bool isConstant,
ConstantInit init,
StringRef section) {
if (!init)
@@ -3502,7 +3502,7 @@
auto alignment = getPointerAlignment();
LinkEntity entity = LinkEntity::forTypeMetadataPattern(D);
auto addr = getAddrOfLLVMVariable(entity, alignment, init,
- Int8PtrTy, DebugTypeInfo());
+ Int8Ty, DebugTypeInfo());
if (init) {
auto var = cast<llvm::GlobalVariable>(addr);
@@ -3565,7 +3565,7 @@
/// Generic arguments.
Int8PtrPtrTy,
/// Generic metadata pattern.
- Int8PtrPtrTy
+ Int8PtrTy
};
fnType = llvm::FunctionType::get(TypeMetadataPtrTy, argTys,
@@ -3577,6 +3577,8 @@
llvm::Type *argTys[] = {
/// Type descriptor.
TypeContextDescriptorPtrTy,
+ /// Resilient metadata pattern.
+ Int8PtrTy
};
fnType = llvm::FunctionType::get(TypeMetadataPtrTy, argTys,
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index c290299..8c21133 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -1245,10 +1245,8 @@
return;
}
- llvm::Function *relocationFunction =
- IGM.getAddrOfTypeMetadataInstantiationFunction(getType(),
- NotForDefinition);
- B.addRelativeAddress(relocationFunction);
+ auto *pattern = IGM.getAddrOfTypeMetadataPattern(Type);
+ B.addRelativeAddress(pattern);
}
ContextDescriptorKind getContextKind() {
@@ -1617,11 +1615,11 @@
IGF.IGM.getPointerSize() * storedProperties.size());
}
-static void emitInitializeMetadata(IRGenFunction &IGF,
- NominalTypeDecl *nominalDecl,
- llvm::Value *metadata,
- bool isVWTMutable,
- MetadataDependencyCollector *collector) {
+static void emitInitializeValueMetadata(IRGenFunction &IGF,
+ NominalTypeDecl *nominalDecl,
+ llvm::Value *metadata,
+ bool isVWTMutable,
+ MetadataDependencyCollector *collector) {
auto loweredTy =
IGF.IGM.getLoweredType(nominalDecl->getDeclaredTypeInContext());
@@ -1992,7 +1990,8 @@
llvm::Value *metadata,
bool isVWTMutable,
MetadataDependencyCollector *collector) {
- ::emitInitializeMetadata(IGF, Target, metadata, isVWTMutable, collector);
+ emitInitializeValueMetadata(IGF, Target, metadata,
+ isVWTMutable, collector);
}
};
} // end anonymous namespace
@@ -2019,6 +2018,23 @@
});
}
+/// Create an access function for the given non-generic type.
+static void createNonGenericMetadataAccessFunction(IRGenModule &IGM,
+ NominalTypeDecl *typeDecl) {
+ assert(!typeDecl->isGenericContext());
+ auto type = typeDecl->getDeclaredType()->getCanonicalType();
+
+ // If the type requires the in-place initialization pattern, use it.
+ if (needsInPlaceMetadataInitialization(IGM, typeDecl)) {
+ createInPlaceInitializationMetadataAccessFunction(IGM, typeDecl, type);
+ return;
+ }
+
+ // Otherwise, use the lazy pattern, which should be emitted using a
+ // direct reference to the metadata.
+ createDirectTypeMetadataAccessFunction(IGM, type, /*allow existing*/ false);
+}
+
// Classes
/// Emit the base-offset variable for the class.
@@ -2169,13 +2185,7 @@
}
void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {
- for (unsigned i = 0,
- e = placeholder->getNumberOfFieldOffsetVectorEntries();
- i < e; ++i) {
- // Emit placeholder values for some number of stored properties we
- // know exist but aren't able to reference directly.
- B.addInt(IGM.SizeTy, 0);
- }
+ llvm_unreachable("Fixed class metadata cannot have missing members");
}
void addMethod(SILDeclRef fn) {
@@ -2261,26 +2271,6 @@
}
};
- /// Utility class for building member metadata for classes with resilient
- /// ancestry. The total size of the class metadata is not known at compile
- /// time, and requires relocation.
- class ResilientClassMemberBuilder {
- public:
- ResilientClassMemberBuilder(IRGenModule &IGM,
- ConstantStructBuilder &builder,
- SILVTable *vtable) {}
-
- void addFieldOffset(VarDecl *var) {}
-
- void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {}
-
- void addMethod(SILDeclRef fn) {}
-
- void addGenericArgument(ClassDecl *forClass) {}
-
- void addGenericWitnessTable(ClassDecl *forClass) {}
- };
-
/// Base class for layout of non-generic class metadata.
template<class Impl, class MemberBuilder>
class ClassMetadataBuilderBase : public ClassMetadataVisitor<Impl> {
@@ -2319,11 +2309,7 @@
void noteResilientSuperclass() {}
- void noteStartOfImmediateMembers(ClassDecl *theClass) {
- if (theClass == Target) {
- emitClassMetadataBaseOffset(IGM, theClass);
- }
- }
+ void noteStartOfImmediateMembers(ClassDecl *theClass) {}
/// The 'metadata flags' field in a class is actually a pointer to
/// the metaclass object for the class.
@@ -2529,17 +2515,11 @@
void createMetadataAccessFunction() {
assert(!Target->isGenericContext());
- auto type =cast<ClassType>(Target->getDeclaredType()->getCanonicalType());
+ emitClassMetadataBaseOffset(IGM, Target);
+ createNonGenericMetadataAccessFunction(IGM, Target);
- // Fixed case.
- if (!doesClassMetadataRequireInitialization(IGM, Target)) {
- (void) createDirectTypeMetadataAccessFunction(IGM, type,
- /*allowExisting*/ false);
+ if (!doesClassMetadataRequireInitialization(IGM, Target))
return;
- }
-
- // Otherwise, we have to initialize metadata at runtime.
- createInPlaceInitializationMetadataAccessFunction(IGM, Target, type);
emitMetadataCompletionFunction(
IGM, Target,
@@ -2548,45 +2528,6 @@
emitInitializeClassMetadata(IGF, Target, FieldLayout, metadata,
collector);
});
-
- // If the class has resilient ancestry we also need a relocation
- // function.
- if (doesClassMetadataRequireRelocation(IGM, Target))
- emitRelocationFunction();
- }
-
- private:
- /// Emit the create function for a class with resilient ancestry.
- void emitRelocationFunction() {
- // using MetadataRelocator =
- // Metadata *(TypeContextDescriptor *type,
- // Metadata *metadata);
- llvm::Function *f =
- IGM.getAddrOfTypeMetadataInstantiationFunction(Target, ForDefinition);
- f->setAttributes(IGM.constructInitialAttributes());
-
- IRGenFunction IGF(IGM, f);
-
- // Skip instrumentation when building for TSan to avoid false positives.
- // The synchronization for this happens in the Runtime and we do not see it.
- if (IGM.IRGen.Opts.Sanitizers & SanitizerKind::Thread)
- f->removeFnAttr(llvm::Attribute::SanitizeThread);
-
- if (IGM.DebugInfo)
- IGM.DebugInfo->emitArtificialFunction(IGF, f);
-
- Explosion params = IGF.collectParameters();
- llvm::Value *descriptor = params.claimNext();
-
- llvm::Value *metadata = IGF.IGM.getAddrOfTypeMetadata(
- Target->getDeclaredType()->getCanonicalType());
-
- // Relocate the metadata.
- auto patternSize = IGM.getSize(Size(B.getNextOffsetFromGlobal()));
- metadata = IGF.Builder.CreateCall(IGF.IGM.getRelocateClassMetadataFn(),
- {descriptor, metadata, patternSize});
-
- IGF.Builder.CreateRet(metadata);
}
};
@@ -2620,18 +2561,120 @@
: super(IGM, theClass, builder, fieldLayout) {}
};
- /// A builder for non-generic class metadata with resilient ancestry.
- class ResilientClassMetadataBuilder :
- public ClassMetadataBuilderBase<ResilientClassMetadataBuilder,
- ResilientClassMemberBuilder> {
- using super = ClassMetadataBuilderBase<ResilientClassMetadataBuilder,
- ResilientClassMemberBuilder>;
+ /// A builder for metadata patterns for non-generic class with
+ /// resilient ancestry.
+ class ResilientClassMetadataBuilder {
+ IRGenModule &IGM;
+ ClassDecl *Target;
+ ConstantStructBuilder &B;
+ const ClassLayout &FieldLayout;
public:
ResilientClassMetadataBuilder(IRGenModule &IGM, ClassDecl *theClass,
ConstantStructBuilder &builder,
const ClassLayout &fieldLayout)
- : super(IGM, theClass, builder, fieldLayout) {}
+ : IGM(IGM), Target(theClass), B(builder), FieldLayout(fieldLayout) {}
+
+ llvm::Constant *emitNominalTypeDescriptor() {
+ return ClassContextDescriptorBuilder(IGM, Target, RequireMetadata).emit();
+ }
+
+ void layout() {
+ emitNominalTypeDescriptor();
+
+ addRelocationFunction();
+ addDestructorFunction();
+ addIVarDestroyer();
+ addClassFlags();
+ addClassDataPointer();
+ addMetaclass();
+ }
+
+ void addRelocationFunction() {
+ auto function = IGM.getAddrOfTypeMetadataInstantiationFunction(
+ Target, NotForDefinition);
+ B.addRelativeAddress(function);
+ }
+
+ void addDestructorFunction() {
+ auto function = getAddrOfDestructorFunction(IGM, Target);
+ B.addRelativeAddressOrNull(function ? *function : nullptr);
+ }
+
+ void addIVarDestroyer() {
+ auto function = IGM.getAddrOfIVarInitDestroy(Target,
+ /*isDestroyer=*/ true,
+ /*isForeign=*/ false,
+ NotForDefinition);
+ B.addRelativeAddressOrNull(function ? *function : nullptr);
+ }
+
+ void addClassFlags() {
+ B.addInt32((uint32_t) getClassFlags(Target));
+ }
+
+ void addClassDataPointer() {
+ auto data = (IGM.ObjCInterop
+ ? emitClassPrivateData(IGM, Target)
+ : nullptr);
+ B.addRelativeAddressOrNull(data);
+ }
+
+ void addMetaclass() {
+ auto metaclass = (IGM.ObjCInterop
+ ? IGM.getAddrOfMetaclassObject(Target, NotForDefinition)
+ : nullptr);
+ B.addRelativeAddressOrNull(metaclass);
+ }
+
+ void createMetadataAccessFunction() {
+ assert(doesClassMetadataRequireRelocation(IGM, Target));
+
+ assert(!Target->isGenericContext());
+ emitClassMetadataBaseOffset(IGM, Target);
+ createNonGenericMetadataAccessFunction(IGM, Target);
+
+ emitMetadataCompletionFunction(
+ IGM, Target,
+ [&](IRGenFunction &IGF, llvm::Value *metadata,
+ MetadataDependencyCollector *collector) {
+ emitInitializeClassMetadata(IGF, Target, FieldLayout, metadata,
+ collector);
+ });
+
+ emitRelocationFunction();
+ }
+
+ private:
+ /// Emit the create function for a class with resilient ancestry.
+ void emitRelocationFunction() {
+ // using MetadataRelocator =
+ // Metadata *(TypeContextDescriptor *type, void *pattern);
+ llvm::Function *f =
+ IGM.getAddrOfTypeMetadataInstantiationFunction(Target, ForDefinition);
+ f->setAttributes(IGM.constructInitialAttributes());
+
+ IRGenFunction IGF(IGM, f);
+
+ // Skip instrumentation when building for TSan to avoid false positives.
+ // The synchronization for this happens in the Runtime and we do not see it.
+ if (IGM.IRGen.Opts.Sanitizers & SanitizerKind::Thread)
+ f->removeFnAttr(llvm::Attribute::SanitizeThread);
+
+ if (IGM.DebugInfo)
+ IGM.DebugInfo->emitArtificialFunction(IGF, f);
+
+ Explosion params = IGF.collectParameters();
+ llvm::Value *descriptor = params.claimNext();
+ llvm::Value *pattern = params.claimNext();
+
+ // Allocate class metadata using the pattern we emitted.
+ llvm::Value *metadata =
+ IGF.Builder.CreateCall(IGF.IGM.getRelocateClassMetadataFn(),
+ {descriptor, pattern});
+
+ IGF.Builder.CreateRet(metadata);
+ }
};
/// A builder for GenericClassMetadataPattern objects.
@@ -2803,7 +2846,8 @@
bool isVWTMutable,
MetadataDependencyCollector *collector) {
assert(!HasDependentVWT && "class should never have dependent VWT");
- emitInitializeClassMetadata(IGF, Target, FieldLayout, metadata, collector);
+ emitInitializeClassMetadata(IGF, Target, FieldLayout,
+ metadata, collector);
}
};
} // end anonymous namespace
@@ -2846,20 +2890,23 @@
auto init = builder.beginStruct();
init.setPacked(true);
- bool isGeneric = classDecl->isGenericContext();
+ // If the class is generic or has resilient ancestry, we emit a pattern,
+ // not type metadata.
+ bool isPattern = doesClassMetadataRequireRelocation(IGM, classDecl);
+
bool canBeConstant;
if (classDecl->isGenericContext()) {
GenericClassMetadataBuilder builder(IGM, classDecl, init,
fieldLayout);
builder.layout();
- canBeConstant = false;
+ canBeConstant = true;
builder.createMetadataAccessFunction();
} else if (doesClassMetadataRequireRelocation(IGM, classDecl)) {
ResilientClassMetadataBuilder builder(IGM, classDecl, init,
fieldLayout);
builder.layout();
- canBeConstant = builder.canBeConstant();
+ canBeConstant = true;
builder.createMetadataAccessFunction();
} else if (doesClassMetadataRequireInitialization(IGM, classDecl)) {
@@ -2885,14 +2932,14 @@
IGM.TargetInfo.OutputObjectFormat == llvm::Triple::MachO)
section = "__DATA,__objc_data, regular";
- auto var = IGM.defineTypeMetadata(declaredType, isGeneric, canBeConstant,
+ auto var = IGM.defineTypeMetadata(declaredType, isPattern, canBeConstant,
init.finishAndCreateFuture(), section);
// Add classes that don't require dynamic initialization to the
// ObjC class list.
//
// FIXME: This is where we check the completely fragile layout.
- if (IGM.ObjCInterop && !isGeneric &&
+ if (IGM.ObjCInterop && !isPattern &&
!doesClassMetadataRequireInitialization(IGM, classDecl)) {
// Emit the ObjC class symbol to make the class visible to ObjC.
if (classDecl->isObjC()) {
@@ -3021,30 +3068,13 @@
emitMetadataCompletionFunction(IGM, Target,
[&](IRGenFunction &IGF, llvm::Value *metadata,
MetadataDependencyCollector *collector) {
- emitInitializeMetadata(IGF, Target, metadata, /*vwt mutable*/true,
- collector);
+ emitInitializeValueMetadata(IGF, Target, metadata,
+ /*vwt mutable*/true, collector);
});
}
};
}
-/// Create an access function for the given non-generic type.
-static void createNonGenericMetadataAccessFunction(IRGenModule &IGM,
- NominalTypeDecl *typeDecl) {
- assert(!typeDecl->isGenericContext());
- auto type = typeDecl->getDeclaredType()->getCanonicalType();
-
- // If the type requires the in-place initialization pattern, use it.
- if (needsInPlaceMetadataInitialization(IGM, typeDecl)) {
- createInPlaceInitializationMetadataAccessFunction(IGM, typeDecl, type);
- return;
- }
-
- // Otherwise, use the lazy pattern, which should be emitted using a
- // direct reference to the metadata.
- createDirectTypeMetadataAccessFunction(IGM, type, /*allow existing*/ false);
-}
-
//===----------------------------------------------------------------------===//
// Structs
@@ -3270,7 +3300,7 @@
GenericStructMetadataBuilder builder(IGM, structDecl, init);
builder.layout();
isPattern = true;
- canBeConstant = false;
+ canBeConstant = true;
builder.createMetadataAccessFunction();
} else {
@@ -3465,7 +3495,7 @@
GenericEnumMetadataBuilder builder(IGM, theEnum, init);
builder.layout();
isPattern = true;
- canBeConstant = false;
+ canBeConstant = true;
builder.createMetadataAccessFunction();
} else {
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 336a432..e813024 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -1168,7 +1168,6 @@
SymbolReferenceKind kind);
llvm::Constant *getAddrOfTypeMetadataPattern(NominalTypeDecl *D);
llvm::Constant *getAddrOfTypeMetadataPattern(NominalTypeDecl *D,
- bool isConstant,
ConstantInit init,
StringRef section);
llvm::Function *getAddrOfTypeMetadataCompletionFunction(NominalTypeDecl *D,
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index b2f0d1a..e90b75a 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -350,7 +350,7 @@
// Initialize the header:
// Heap destructor.
- fullMetadata->destroy = pattern->Destroy;
+ fullMetadata->destroy = pattern->Destroy.get();
// Value witness table.
#if SWIFT_OBJC_INTEROP
@@ -2121,29 +2121,83 @@
ClassMetadata *
swift::swift_relocateClassMetadata(ClassDescriptor *description,
- ClassMetadata *pattern,
- size_t patternSize) {
+ ResilientClassMetadataPattern *pattern) {
auto bounds = description->getMetadataBounds();
- auto metadataSize = bounds.getTotalSizeInBytes();
- if (patternSize < metadataSize) {
- auto bytes = (char*) malloc(metadataSize);
+ auto metadata = reinterpret_cast<ClassMetadata *>(
+ (char*) malloc(bounds.getTotalSizeInBytes()) +
+ bounds.getAddressPointInBytes());
+ auto fullMetadata = asFullMetadata(metadata);
+ char *rawMetadata = reinterpret_cast<char*>(metadata);
- auto fullPattern = (const char*) pattern;
- fullPattern -= pattern->getClassAddressPoint();
- memcpy(bytes, fullPattern, patternSize);
- memset(bytes + patternSize, 0,
- metadataSize - patternSize);
+ // Zero out the entire immediate-members section.
+ void **immediateMembers =
+ reinterpret_cast<void**>(rawMetadata + bounds.ImmediateMembersOffset);
+ memset(immediateMembers, 0, description->getImmediateMembersSize());
- auto addressPoint = bytes + bounds.getAddressPointInBytes();
- auto metadata = reinterpret_cast<ClassMetadata *>(addressPoint);
+ // Initialize the header:
- metadata->setClassSize(metadataSize);
- assert(metadata->isTypeMetadata());
- return metadata;
- }
+ // Heap destructor.
+ fullMetadata->destroy = pattern->Destroy.get();
- return pattern;
+ // Value witness table.
+#if SWIFT_OBJC_INTEROP
+ fullMetadata->ValueWitnesses =
+ (pattern->Flags & ClassFlags::UsesSwiftRefcounting)
+ ? &VALUE_WITNESS_SYM(Bo)
+ : &VALUE_WITNESS_SYM(BO);
+#else
+ fullMetadata->ValueWitnesses = &VALUE_WITNESS_SYM(Bo);
+#endif
+
+ // MetadataKind / isa.
+#if SWIFT_OBJC_INTEROP
+ metadata->setClassISA(pattern->Metaclass.get());
+#else
+ metadata->setKind(MetadataKind::Class);
+#endif
+
+ // Superclass.
+ metadata->Superclass = nullptr;
+
+#if SWIFT_OBJC_INTEROP
+ // Cache data. Install the same initializer that the compiler is
+ // required to use. We don't need to do this in non-ObjC-interop modes.
+ metadata->CacheData[0] = &_objc_empty_cache;
+ metadata->CacheData[1] = nullptr;
+#endif
+
+ // RO-data pointer.
+#if SWIFT_OBJC_INTEROP
+ auto classRO = pattern->Data.get();
+ metadata->Data =
+ reinterpret_cast<uintptr_t>(classRO) | SWIFT_CLASS_IS_SWIFT_MASK;
+#else
+ metadata->Data = SWIFT_CLASS_IS_SWIFT_MASK;
+#endif
+
+ // Class flags.
+ metadata->Flags = pattern->Flags;
+
+ // Instance layout.
+ metadata->InstanceAddressPoint = 0;
+ metadata->InstanceSize = 0;
+ metadata->InstanceAlignMask = 0;
+
+ // Reserved.
+ metadata->Reserved = 0;
+
+ // Class metadata layout.
+ metadata->ClassSize = bounds.getTotalSizeInBytes();
+ metadata->ClassAddressPoint = bounds.getAddressPointInBytes();
+
+ // Class descriptor.
+ metadata->setDescription(description);
+
+ // I-var destroyer.
+ metadata->IVarDestroyer = pattern->IVarDestroyer;
+
+ return metadata;
}
/// Initialize the field offset vector for a dependent-layout class, using the
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index dcc0a26f..04d693a 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -3,7 +3,7 @@
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift
-// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience %t/class_resilience.swift | %FileCheck %t/class_resilience.swift --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience %t/class_resilience.swift | %FileCheck %t/class_resilience.swift --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-runtime -DINT=i%target-ptrsize
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience -O %t/class_resilience.swift
// CHECK: @"$S16class_resilience26ClassWithResilientPropertyC1s16resilient_struct4SizeVvpWvd" = hidden global [[INT]] 0
@@ -33,14 +33,50 @@
// CHECK: @"$S16class_resilience14ResilientChildCMn" = {{(protected )?}}{{(dllexport )?}}constant <{{.*}}> <{
// -- flags: class, unique, has vtable, in-place initialization, has resilient superclass
// CHECK-SAME: <i32 0xC401_0050>
+// -- parent:
+// CHECK-SAME: @"$S16class_resilienceMXM"
// -- name:
// CHECK-SAME: [15 x i8]* [[RESILIENTCHILD_NAME]]
-// -- num fields
+// -- metadata accessor function:
+// CHECK-SAME: @"$S16class_resilience14ResilientChildCMa"
+// -- field descriptor:
+// CHECK-SAME: @"$S16class_resilience14ResilientChildCMF"
+// -- superclass:
+// CHECK-SAME: @"got.$S15resilient_class22ResilientOutsideParentCMn"
+// -- metadata bounds:
+// CHECK-SAME: @"$S16class_resilience14ResilientChildCMo"
+// -- metadata positive size in words (not used):
+// CHECK-SAME: i32 0,
+// -- num immediate members:
+// CHECK-SAME: i32 4,
+// -- num fields:
// CHECK-SAME: i32 1,
-// -- field offset vector offset
+// -- field offset vector offset:
// CHECK-SAME: i32 3,
+// -- singleton metadata initialization cache:
+// CHECK-SAME: @"$S16class_resilience14ResilientChildCMl"
+// -- resilient pattern:
+// CHECK-SAME: @"$S16class_resilience14ResilientChildCMP"
+// -- completion function:
+// CHECK-SAME: @"$S16class_resilience14ResilientChildCMr"
// CHECK-SAME: }>
+// CHECK: @"$S16class_resilience14ResilientChildCMP" = internal constant <{{.*}}> <{
+// -- instantiation function:
+// CHECK-SAME: @"$S16class_resilience14ResilientChildCMi"
+// -- destructor:
+// CHECK-SAME: @"$S16class_resilience14ResilientChildCfD"
+// -- ivar destroyer:
+// CHECK-SAME: i32 0,
+// -- flags:
+// CHECK-SAME: i32 3,
+// -- RO data:
+// CHECK-objc-SAME: @_DATA__TtC16class_resilience14ResilientChild
+// CHECK-native-SAME: i32 0,
+// -- metaclass:
+// CHECK-objc-SAME: @"$S16class_resilience14ResilientChildCMm"
+// CHECK-native-SAME: i32 0
+
// CHECK: @"$S16class_resilience16FixedLayoutChildCMo" = {{(protected )?}}{{(dllexport )?}}global [[BOUNDS]] zeroinitializer
// CHECK: @"$S16class_resilience17MyResilientParentCMo" = {{(protected )?}}{{(dllexport )?}}constant [[BOUNDS]]
@@ -361,10 +397,10 @@
// CHECK: void @swift_initClassMetadata(%swift.type* %0, %swift.type* null, [[INT]] 256, [[INT]] 3, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]])
// CHECK-native: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}}
-// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience26ClassWithResilientPropertyC1s16resilient_struct4SizeVvWvd"
+// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience26ClassWithResilientPropertyC1s16resilient_struct4SizeVvpWvd"
// CHECK-native: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}}
-// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience26ClassWithResilientPropertyC5colors5Int32VvWvd"
+// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience26ClassWithResilientPropertyC5colors5Int32VvpWvd"
// CHECK: br label %metadata-dependencies.cont
@@ -400,10 +436,10 @@
// CHECK: call void @swift_initClassMetadata(%swift.type* %0, %swift.type* null, [[INT]] 256, [[INT]] 2, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]])
// CHECK-native: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}}
-// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience33ClassWithResilientlySizedPropertyC1r16resilient_struct9RectangleVvWvd"
+// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience33ClassWithResilientlySizedPropertyC1r16resilient_struct9RectangleVvpWvd"
// CHECK-native: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}}
-// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience33ClassWithResilientlySizedPropertyC5colors5Int32VvWvd"
+// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience33ClassWithResilientlySizedPropertyC5colors5Int32VvpWvd"
// CHECK: br label %metadata-dependencies.cont
@@ -416,14 +452,6 @@
// CHECK-NEXT: ret %swift.metadata_response [[T1]]
-// ResilientChild metadata relocation function
-
-// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience14ResilientChildCMi"(%swift.type_descriptor*)
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, %swift.type* bitcast ({{.*}} @"$S16class_resilience14ResilientChildCMf", {{.*}}), [[INT]] {{60|96}})
-// CHECK-NEXT: ret %swift.type* [[METADATA]]
-
-
// ResilientChild metadata initialization function
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$S16class_resilience14ResilientChildCMr"(%swift.type*, i8*, i8**)
@@ -467,6 +495,14 @@
// CHECK-NEXT: ret %swift.metadata_response [[T1]]
+// ResilientChild metadata relocation function
+
+// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience14ResilientChildCMi"(%swift.type_descriptor*, i8*)
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, i8* %1)
+// CHECK-NEXT: ret %swift.type* [[METADATA]]
+
+
// ResilientChild.field setter dispatch thunk
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$S16class_resilience14ResilientChildC5fields5Int32VvsTj"(i32, %T16class_resilience14ResilientChildC* swiftself)
@@ -482,14 +518,6 @@
// CHECK-NEXT: ret void
-// FixedLayoutChild metadata relocation function
-
-// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience16FixedLayoutChildCMi"(%swift.type_descriptor*)
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, %swift.type* bitcast ({{.*}} @"$S16class_resilience16FixedLayoutChildCMf", {{.*}}), [[INT]] {{60|96}})
-// CHECK-NEXT: ret %swift.type* [[METADATA]]
-
-
// FixedLayoutChild metadata initialization function
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$S16class_resilience16FixedLayoutChildCMr"(%swift.type*, i8*, i8**)
@@ -516,10 +544,18 @@
// CHECK-NEXT: ret %swift.metadata_response [[T1]]
+// FixedLayoutChild metadata relocation function
+
+// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience16FixedLayoutChildCMi"(%swift.type_descriptor*, i8*)
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, i8* %1)
+// CHECK-NEXT: ret %swift.type* [[METADATA]]
+
+
// ResilientGenericChild metadata initialization function
-// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience21ResilientGenericChildCMi"(%swift.type_descriptor*, i8**, i8**)
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience21ResilientGenericChildCMi"(%swift.type_descriptor*, i8**, i8*)
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
// CHECK: ret %swift.type* [[METADATA]]
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$S16class_resilience21ResilientGenericChildCMr"
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index 5076f51..18b4e89 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -2633,10 +2633,10 @@
}
// -- Fill function for dynamic singleton.
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S4enum16DynamicSingletonOMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S4enum16DynamicSingletonOMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: [[T:%T]] = load %swift.type*, %swift.type** [[T0]],
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2, [[WORD]] {{4|8}})
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2, [[WORD]] {{4|8}})
// CHECK-NEXT: ret %swift.type* [[METADATA]]
// CHECK-LABEL: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$S4enum16DynamicSingletonOMr"
diff --git a/test/IRGen/enum_dynamic_multi_payload.sil b/test/IRGen/enum_dynamic_multi_payload.sil
index 331f184..2a2080d 100644
--- a/test/IRGen/enum_dynamic_multi_payload.sil
+++ b/test/IRGen/enum_dynamic_multi_payload.sil
@@ -417,7 +417,7 @@
return undef : $()
}
-// CHECK: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S26enum_dynamic_multi_payload8EitherOrOMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S26enum_dynamic_multi_payload8EitherOrOMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata
// CHECK: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$S26enum_dynamic_multi_payload8EitherOrOMr"
diff --git a/test/IRGen/enum_value_semantics.sil b/test/IRGen/enum_value_semantics.sil
index 4ce6124..8cba4d2 100644
--- a/test/IRGen/enum_value_semantics.sil
+++ b/test/IRGen/enum_value_semantics.sil
@@ -167,7 +167,7 @@
// CHECK-LABEL: @"$S20enum_value_semantics18GenericFixedLayoutOMP" = internal constant <{ {{.*}} }> <{
// Instantiation function.
-// CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint (%swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S20enum_value_semantics18GenericFixedLayoutOMi" to i64), i64 ptrtoint (<{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP" to i64)) to i32),
+// CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint (%swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S20enum_value_semantics18GenericFixedLayoutOMi" to i64), i64 ptrtoint (<{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP" to i64)) to i32),
// Completion function.
// CHECK-SAME: i32 0,
// Pattern flags. 0x4020_0000 == (MetadataKind::Enum << 21).
diff --git a/test/IRGen/generic_classes.sil b/test/IRGen/generic_classes.sil
index 407da21..e1eb794 100644
--- a/test/IRGen/generic_classes.sil
+++ b/test/IRGen/generic_classes.sil
@@ -44,7 +44,7 @@
// CHECK-LABEL: @"$S15generic_classes11RootGenericCMP" = internal constant
// CHECK-SAME: <{
// -- template instantiation function
-// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_classes11RootGenericCMi"
+// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S15generic_classes11RootGenericCMi"
// -- heap destructor
// CHECK-SAME: @"$S15generic_classes11RootGenericCfD"
// -- ivar destroyer
@@ -113,7 +113,7 @@
// CHECK: @"$S15generic_classes015GenericInheritsC0CMP" = internal constant
// -- template instantiation function
-// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_classes015GenericInheritsC0CMi"
+// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S15generic_classes015GenericInheritsC0CMi"
// -- pattern flags (1 == has extra data pattern)
// CHECK-SAME-native: i32 0,
// CHECK-SAME-objc: i32 1,
@@ -339,8 +339,8 @@
}
*/
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
-// CHECK: [[METADATA:%.*]] = call{{( tail)?}} %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
+// CHECK: [[METADATA:%.*]] = call{{( tail)?}} %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal swiftcc %swift.metadata_response @"$S15generic_classes11RootGenericCMr"
// CHECK-SAME: (%swift.type* [[METADATA:%.*]], i8*, i8**) {{.*}} {
@@ -348,22 +348,22 @@
// CHECK: call void @swift_initClassMetadata(%swift.type* [[METADATA]], %swift.type* null, i64 0, i64 3, i8*** {{%.*}}, i64* {{%.*}})
// CHECK: }
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
-// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
+// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal swiftcc %swift.metadata_response @"$S15generic_classes22RootGenericFixedLayoutCMr"
// CHECK-SAME: (%swift.type* [[METADATA:%.*]], i8*, i8**) {{.*}} {
// CHECK: call void @swift_initClassMetadata(%swift.type* [[METADATA]], %swift.type* null, i64 0, i64 3, i8*** {{%.*}}, i64* {{%.*}})
// CHECK: }
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes015GenericInheritsC0CMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes015GenericInheritsC0CMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
// Bind the generic parameters.
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %A = load %swift.type*, %swift.type** [[T0]]
// CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
// CHECK: %B = load %swift.type*, %swift.type** [[T1]]
// Construct the class.
-// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
// CHECK-NEXT: ret %swift.type* [[METADATA]]
// CHECK-LABEL: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$S15generic_classes015GenericInheritsC0CMr"
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 00e30a0..eba7d27 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -11,7 +11,7 @@
// CHECK: [[PATTERN:@.*]] = internal constant [4 x i32] [i32 0, i32 1, i32 8, i32 0]
// CHECK-LABEL: @"$S15generic_structs18FixedLayoutGenericVMP" = internal constant <{ {{.*}} }> <{
// -- instantiation function
-// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_structs18FixedLayoutGenericVMi"
+// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S15generic_structs18FixedLayoutGenericVMi"
// -- completion function
// CHECK-SAME: i32 0,
// -- pattern flags
@@ -56,7 +56,7 @@
// CHECK-SAME: }>
// CHECK: @"$S15generic_structs13SingleDynamicVMP" = internal constant <{ {{.*}} }> <{
// -- instantiation function
-// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_structs13SingleDynamicVMi"
+// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S15generic_structs13SingleDynamicVMi"
// -- vwtable pointer
// CHECK-SAME: @"$S15generic_structs13SingleDynamicVWV"
@@ -195,10 +195,10 @@
return %v : $()
}
-// CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_structs13SingleDynamicVMi"(%swift.type_descriptor*, i8**, i8**)
+// CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_structs13SingleDynamicVMi"(%swift.type_descriptor*, i8**, i8*)
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %T = load %swift.type*, %swift.type** [[T0]], align 8
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2, i64 16)
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2, i64 16)
// CHECK-NEXT: ret %swift.type* [[METADATA]]
// CHECK: }
diff --git a/test/IRGen/generic_types.swift b/test/IRGen/generic_types.swift
index d8b5df0..d93d05e 100644
--- a/test/IRGen/generic_types.swift
+++ b/test/IRGen/generic_types.swift
@@ -93,17 +93,17 @@
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: }
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S13generic_types1ACMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S13generic_types1ACMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %T = load %swift.type*, %swift.type** [[T0]],
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
// CHECK-NEXT: ret %swift.type* [[METADATA]]
// CHECK: }
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S13generic_types1BCMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S13generic_types1BCMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %T = load %swift.type*, %swift.type** [[T0]],
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
// CHECK-NEXT: ret %swift.type* [[METADATA]]
// CHECK: }
diff --git a/test/IRGen/generic_vtable.swift b/test/IRGen/generic_vtable.swift
index 3a49a06..e8c15f8 100644
--- a/test/IRGen/generic_vtable.swift
+++ b/test/IRGen/generic_vtable.swift
@@ -110,12 +110,12 @@
//// Metadata initialization function for 'Derived' copies superclass vtable
//// and installs overrides for 'm2()' and 'init()'.
-// CHECK-LABEL: define internal %swift.type* @"$S14generic_vtable7DerivedCMi"(%swift.type_descriptor*, i8**, i8**)
+// CHECK-LABEL: define internal %swift.type* @"$S14generic_vtable7DerivedCMi"(%swift.type_descriptor*, i8**, i8*)
// - 2 immediate members:
// - type metadata for generic parameter T,
// - and vtable entry for 'm3()'
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
// CHECK: ret %swift.type* [[METADATA]]
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$S14generic_vtable7DerivedCMr"
diff --git a/test/multifile/require-layout-generic-arg-closure.swift b/test/multifile/require-layout-generic-arg-closure.swift
index 49b7bf2..6d7b299 100644
--- a/test/multifile/require-layout-generic-arg-closure.swift
+++ b/test/multifile/require-layout-generic-arg-closure.swift
@@ -17,7 +17,7 @@
public func requestType2<T>(x: T) {
requestTypeThrough(closure: { x in print(x) }, arg: x)
}
-// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8**)
+// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8*)
// FILE2: [[T_ADDR:%.*]] = bitcast i8** %1 to %swift.type**
// FILE2: [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
// FILE2: [[CLASSMETADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata
diff --git a/test/multifile/require-layout-generic-arg-subscript.swift b/test/multifile/require-layout-generic-arg-subscript.swift
index fe8e1e2..7eb7f65 100644
--- a/test/multifile/require-layout-generic-arg-subscript.swift
+++ b/test/multifile/require-layout-generic-arg-subscript.swift
@@ -21,7 +21,7 @@
}
}
-// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8**)
+// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8*)
// FILE2: [[T_ADDR:%.*]] = bitcast i8** %1 to %swift.type**
// FILE2: [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
// FILE2: [[CLASSMETADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata
diff --git a/test/multifile/require-layout-generic-arg.swift b/test/multifile/require-layout-generic-arg.swift
index 0f2ebc0..9c7af0c 100644
--- a/test/multifile/require-layout-generic-arg.swift
+++ b/test/multifile/require-layout-generic-arg.swift
@@ -15,7 +15,7 @@
print(T.self)
}
-// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8**)
+// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8*)
// FILE2: [[T_ADDR:%.*]] = bitcast i8** %1 to %swift.type**
// FILE2: [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
// FILE2: [[CLASSMETADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata