@@ -656,6 +656,14 @@ emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
656656
657657void IRGenModule::emitRuntimeRegistration () {
658658 // Duck out early if we have nothing to register.
659+ // Note that we don't consider `RuntimeResolvableTypes2` here because the
660+ // current Swift runtime is unable to handle move-only types at runtime, and
661+ // we only use this runtime registration path in JIT mode, so there are no
662+ // ABI forward compatibility concerns.
663+ //
664+ // We should incorporate the types from
665+ // `RuntimeResolvableTypes2` into the list of types to register when we do
666+ // have runtime support in place.
659667 if (SwiftProtocols.empty () && ProtocolConformances.empty () &&
660668 RuntimeResolvableTypes.empty () &&
661669 (!ObjCInterop || (ObjCProtocols.empty () && ObjCClasses.empty () &&
@@ -1033,7 +1041,16 @@ void IRGenModule::addObjCClassStub(llvm::Constant *classPtr) {
10331041
10341042void IRGenModule::addRuntimeResolvableType (GenericTypeDecl *type) {
10351043 // Collect the nominal type records we emit into a special section.
1036- RuntimeResolvableTypes.push_back (type);
1044+ if (type->isMoveOnly ()) {
1045+ // Older runtimes should not be allowed to discover noncopyable types, since
1046+ // they will try to expose them dynamically as copyable types. Record
1047+ // noncopyable type descriptors in a separate vector so that future
1048+ // noncopyable-type-aware runtimes and reflection libraries can still find
1049+ // them.
1050+ RuntimeResolvableTypes2.push_back (type);
1051+ } else {
1052+ RuntimeResolvableTypes.push_back (type);
1053+ }
10371054
10381055 if (auto nominal = dyn_cast<NominalTypeDecl>(type)) {
10391056 // As soon as the type metadata is available, all the type's conformances
@@ -4202,21 +4219,26 @@ llvm::Constant *IRGenModule::emitProtocolConformances(bool asContiguousArray) {
42024219// / otherwise the descriptors are emitted as individual globals and nullptr is
42034220// / returned).
42044221llvm::Constant *IRGenModule::emitTypeMetadataRecords (bool asContiguousArray) {
4205- if (RuntimeResolvableTypes.empty ())
4222+ if (RuntimeResolvableTypes.empty ()
4223+ && RuntimeResolvableTypes2.empty ())
42064224 return nullptr ;
42074225
42084226 std::string sectionName;
4227+ std::string section2Name;
42094228 switch (TargetInfo.OutputObjectFormat ) {
42104229 case llvm::Triple::MachO:
42114230 sectionName = " __TEXT, __swift5_types, regular" ;
4231+ section2Name = " __TEXT, __swift5_types2, regular" ;
42124232 break ;
42134233 case llvm::Triple::ELF:
42144234 case llvm::Triple::Wasm:
42154235 sectionName = " swift5_type_metadata" ;
4236+ section2Name = " swift5_type_metadata_2" ;
42164237 break ;
42174238 case llvm::Triple::XCOFF:
42184239 case llvm::Triple::COFF:
42194240 sectionName = " .sw5tymd$B" ;
4241+ section2Name = " .sw5tym2$B" ;
42204242 break ;
42214243 case llvm::Triple::DXContainer:
42224244 case llvm::Triple::GOFF:
@@ -4276,39 +4298,50 @@ llvm::Constant *IRGenModule::emitTypeMetadataRecords(bool asContiguousArray) {
42764298 }
42774299
42784300 // In non-JIT mode, emit the type records as individual globals.
4279- for (auto type : RuntimeResolvableTypes) {
4280- auto ref = getTypeEntityReference (type);
4281-
4282- std::string recordMangledName;
4283- if (auto opaque = dyn_cast<OpaqueTypeDecl>(type)) {
4284- recordMangledName =
4285- LinkEntity::forOpaqueTypeDescriptorRecord (opaque).mangleAsString ();
4286- } else if (auto nominal = dyn_cast<NominalTypeDecl>(type)) {
4287- recordMangledName =
4288- LinkEntity::forNominalTypeDescriptorRecord (nominal).mangleAsString ();
4289- } else {
4290- llvm_unreachable (" bad type in RuntimeResolvableTypes" );
4301+
4302+ auto generateGlobalTypeList = [&](ArrayRef<GenericTypeDecl *> typesList,
4303+ StringRef section) {
4304+ if (typesList.empty ()) {
4305+ return ;
42914306 }
4307+
4308+ for (auto type : typesList) {
4309+ auto ref = getTypeEntityReference (type);
42924310
4293- auto var = new llvm::GlobalVariable (
4294- Module, TypeMetadataRecordTy, /* isConstant*/ true ,
4295- llvm::GlobalValue::PrivateLinkage, /* initializer*/ nullptr ,
4296- recordMangledName);
4311+ std::string recordMangledName;
4312+ if (auto opaque = dyn_cast<OpaqueTypeDecl>(type)) {
4313+ recordMangledName =
4314+ LinkEntity::forOpaqueTypeDescriptorRecord (opaque).mangleAsString ();
4315+ } else if (auto nominal = dyn_cast<NominalTypeDecl>(type)) {
4316+ recordMangledName =
4317+ LinkEntity::forNominalTypeDescriptorRecord (nominal).mangleAsString ();
4318+ } else {
4319+ llvm_unreachable (" bad type in RuntimeResolvableTypes" );
4320+ }
42974321
4298- auto record = generateRecord (ref, var, {0 });
4299- var->setInitializer (record);
4322+ auto var = new llvm::GlobalVariable (
4323+ Module, TypeMetadataRecordTy, /* isConstant*/ true ,
4324+ llvm::GlobalValue::PrivateLinkage, /* initializer*/ nullptr ,
4325+ recordMangledName);
43004326
4301- var->setSection (sectionName);
4302- var->setAlignment (llvm::MaybeAlign (4 ));
4303- disableAddressSanitizer (*this , var);
4304- addUsedGlobal (var);
4327+ auto record = generateRecord (ref, var, {0 });
4328+ var->setInitializer (record);
43054329
4306- if (IRGen.Opts .ConditionalRuntimeRecords ) {
4307- // Allow dead-stripping `var` (the type record) when the type (`ref`) is
4308- // not referenced.
4309- appendLLVMUsedConditionalEntry (var, ref.getValue ());
4330+ var->setSection (section);
4331+ var->setAlignment (llvm::MaybeAlign (4 ));
4332+ disableAddressSanitizer (*this , var);
4333+ addUsedGlobal (var);
4334+
4335+ if (IRGen.Opts .ConditionalRuntimeRecords ) {
4336+ // Allow dead-stripping `var` (the type record) when the type (`ref`) is
4337+ // not referenced.
4338+ appendLLVMUsedConditionalEntry (var, ref.getValue ());
4339+ }
43104340 }
4311- }
4341+ };
4342+
4343+ generateGlobalTypeList (RuntimeResolvableTypes, sectionName);
4344+ generateGlobalTypeList (RuntimeResolvableTypes2, section2Name);
43124345
43134346 return nullptr ;
43144347}
0 commit comments