Skip to content

Commit df7744e

Browse files
authored
Merge pull request swiftlang#19480 from DougGregor/mangled-assoc-type-witness
[ABI] Use mangled names for associated type witnesses.
2 parents 01f9fdc + 9a403a0 commit df7744e

32 files changed

+449
-534
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ Globals
9090
global ::= protocol-conformance 'WI' // generic protocol witness table instantiation function
9191
global ::= type protocol-conformance 'WL' // lazy protocol witness table cache variable
9292

93-
global ::= protocol-conformance identifier 'Wt' // associated type metadata accessor
93+
global ::= protocol-conformance identifier 'Wt' // associated type metadata accessor (HISTORICAL)
9494
global ::= protocol-conformance assoc-type-list nominal-type 'WT' // associated type witness table accessor
9595
global ::= type protocol-conformance 'Wl' // lazy protocol witness table accessor
9696

@@ -138,7 +138,7 @@ types where the metadata itself has unknown layout.)
138138

139139
global ::= protocol 'TL' // protocol requirements base descriptor
140140
global ::= assoc-type-name 'Tl' // associated type descriptor
141-
global ::= assoc-type-name 'TM' // default associated type witness accessor
141+
global ::= assoc-type-name 'TM' // default associated type witness accessor (HISTORICAL)
142142
global ::= type assoc-type-path protocol 'Tn' // associated conformance descriptor
143143
global ::= type assoc-type-path protocol 'TN' // default associated conformance witness accessor
144144

include/swift/ABI/Metadata.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,11 +1700,6 @@ using TargetWitnessTablePointer =
17001700

17011701
using WitnessTablePointer = TargetWitnessTablePointer<InProcess>;
17021702

1703-
using AssociatedTypeAccessFunction =
1704-
SWIFT_CC(swift) MetadataResponse(MetadataRequest request,
1705-
const Metadata *self,
1706-
const WitnessTable *selfConformance);
1707-
17081703
using AssociatedWitnessTableAccessFunction =
17091704
SWIFT_CC(swift) WitnessTable *(const Metadata *associatedType,
17101705
const Metadata *self,
@@ -2013,7 +2008,10 @@ struct TargetGenericWitnessTable {
20132008
/// The amount of private storage to allocate before the address point,
20142009
/// in words. This memory is zeroed out in the instantiated witness table
20152010
/// template.
2016-
uint16_t WitnessTablePrivateSizeInWords;
2011+
///
2012+
/// The low bit is used to indicate whether this witness table is known
2013+
/// to require instantiation.
2014+
uint16_t WitnessTablePrivateSizeInWordsAndRequiresInstantiation;
20172015

20182016
/// The protocol descriptor. Only used for resilient conformances.
20192017
RelativeIndirectablePointer<ProtocolDescriptor,
@@ -2037,6 +2035,15 @@ struct TargetGenericWitnessTable {
20372035
/// Private data for the instantiator. Out-of-line so that the rest
20382036
/// of this structure can be constant.
20392037
RelativeDirectPointer<PrivateDataType> PrivateData;
2038+
2039+
uint16_t getWitnessTablePrivateSizeInWords() const {
2040+
return WitnessTablePrivateSizeInWordsAndRequiresInstantiation >> 1;
2041+
}
2042+
2043+
/// Whether the witness table is known to require instantiation.
2044+
uint16_t requiresInstantiation() const {
2045+
return WitnessTablePrivateSizeInWordsAndRequiresInstantiation & 0x01;
2046+
}
20402047
};
20412048
using GenericWitnessTable = TargetGenericWitnessTable<InProcess>;
20422049

@@ -2238,8 +2245,7 @@ struct TargetProtocolConformanceDescriptor final
22382245
public:
22392246
using WitnessTableAccessorFn
22402247
= const TargetWitnessTable<Runtime> *(const TargetMetadata<Runtime>*,
2241-
const TargetWitnessTable<Runtime> **,
2242-
size_t);
2248+
const TargetWitnessTable<Runtime> **);
22432249

22442250
using GenericRequirementDescriptor =
22452251
TargetGenericRequirementDescriptor<Runtime>;

include/swift/ABI/MetadataValues.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,19 @@ class ProtocolRequirementFlags {
580580
bool isInstance() const { return Value & IsInstanceMask; }
581581

582582
int_type getIntValue() const { return Value; }
583+
584+
enum : uintptr_t {
585+
/// Bit used to indicate that an associated type witness is a pointer to
586+
/// a mangled name (vs. a pointer to metadata).
587+
AssociatedTypeMangledNameBit = 0x01,
588+
};
589+
590+
enum : uint8_t {
591+
/// Prefix byte used to identify an associated type whose mangled name
592+
/// is relative to the protocol's context rather than the conforming
593+
/// type's context.
594+
AssociatedTypeInProtocolContextByte = 0xFF
595+
};
583596
};
584597

585598
/// Flags that go in a TargetConformanceDescriptor structure.

include/swift/IRGen/Linking.h

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,6 @@ class LinkEntity {
218218
/// is stored in the data.
219219
DefaultAssociatedConformanceAccessor,
220220

221-
/// A function which returns the default type metadata for the associated
222-
/// type of a protocol. The secondary pointer is a ProtocolDecl*.
223-
/// The index of the associated type declaration is stored in the data.
224-
DefaultAssociatedTypeMetadataAccessFunction,
225-
226221
/// A SIL function. The pointer is a SILFunction*.
227222
SILFunction,
228223

@@ -263,11 +258,6 @@ class LinkEntity {
263258
/// A list of key/value pairs that resiliently specify a witness table.
264259
ResilientProtocolWitnessTable,
265260

266-
/// A function which returns the type metadata for the associated type
267-
/// of a protocol. The secondary pointer is a ProtocolConformance*.
268-
/// The index of the associated type declaration is stored in the data.
269-
AssociatedTypeMetadataAccessFunction,
270-
271261
/// A function which returns the witness table for a protocol-constrained
272262
/// associated type of a protocol. The secondary pointer is a
273263
/// ProtocolConformance*. The index of the associated conformance
@@ -336,7 +326,7 @@ class LinkEntity {
336326
}
337327

338328
static bool isDeclKind(Kind k) {
339-
return k <= Kind::DefaultAssociatedTypeMetadataAccessFunction;
329+
return k <= Kind::DefaultAssociatedConformanceAccessor;
340330
}
341331
static bool isTypeKind(Kind k) {
342332
return k >= Kind::ProtocolWitnessTableLazyAccessFunction;
@@ -810,24 +800,6 @@ class LinkEntity {
810800
return entity;
811801
}
812802

813-
static LinkEntity
814-
forAssociatedTypeMetadataAccessFunction(const ProtocolConformance *C,
815-
AssociatedType association) {
816-
LinkEntity entity;
817-
entity.setForProtocolConformanceAndAssociatedType(
818-
Kind::AssociatedTypeMetadataAccessFunction, C,
819-
association.getAssociation());
820-
return entity;
821-
}
822-
823-
static LinkEntity
824-
forDefaultAssociatedTypeMetadataAccessFunction(AssociatedType association) {
825-
LinkEntity entity;
826-
entity.setForDecl(Kind::DefaultAssociatedTypeMetadataAccessFunction,
827-
association.getAssociation());
828-
return entity;
829-
}
830-
831803
static LinkEntity
832804
forAssociatedTypeWitnessTableAccessFunction(const ProtocolConformance *C,
833805
const AssociatedConformance &association) {
@@ -925,12 +897,7 @@ class LinkEntity {
925897
}
926898

927899
AssociatedTypeDecl *getAssociatedType() const {
928-
if (getKind() == Kind::AssociatedTypeMetadataAccessFunction)
929-
return getAssociatedTypeByIndex(getProtocolConformance(),
930-
LINKENTITY_GET_FIELD(Data, AssociatedTypeIndex));
931-
932-
assert(getKind() == Kind::AssociatedTypeDescriptor ||
933-
getKind() == Kind::DefaultAssociatedTypeMetadataAccessFunction);
900+
assert(getKind() == Kind::AssociatedTypeDescriptor);
934901
return reinterpret_cast<AssociatedTypeDecl *>(Pointer);
935902
}
936903

include/swift/Runtime/Metadata.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,20 @@ swift_getGenericWitnessTable(GenericWitnessTable *genericTable,
410410
const Metadata *type,
411411
void **const *instantiationArgs);
412412

413+
/// Retrieve an associated type witness from the given witness table.
414+
///
415+
/// \param wtable The witness table.
416+
/// \param conformingType Metadata for the conforming type.
417+
/// \param assocType Associated type descriptor.
418+
///
419+
/// \returns metadata for the associated type witness.
420+
SWIFT_RUNTIME_EXPORT
421+
MetadataResponse swift_getAssociatedTypeWitness(
422+
MetadataRequest request,
423+
WitnessTable *wtable,
424+
const Metadata *conformingType,
425+
const ProtocolRequirement *assocType);
426+
413427
/// \brief Fetch a uniqued metadata for a function type.
414428
SWIFT_RUNTIME_EXPORT
415429
const FunctionTypeMetadata *

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,19 @@ FUNCTION(GetGenericWitnessTable, swift_getGenericWitnessTable, C_CC,
645645
WitnessTablePtrPtrTy),
646646
ATTRS(NoUnwind, ReadOnly))
647647

648+
// MetadataResponse swift_getAssociatedTypeWitness(
649+
// MetadataRequest request,
650+
// WitnessTable *wtable,
651+
// const Metadata *conformingType,
652+
// ProtocolRequirement *assocType);
653+
FUNCTION(GetAssociatedTypeWitness, swift_getAssociatedTypeWitness, C_CC,
654+
RETURNS(TypeMetadataResponseTy),
655+
ARGS(SizeTy,
656+
WitnessTablePtrTy,
657+
TypeMetadataPtrTy,
658+
ProtocolRequirementStructTy->getPointerTo()),
659+
ATTRS(NoUnwind, ReadNone))
660+
648661
// Metadata *swift_getMetatypeMetadata(Metadata *instanceTy);
649662
FUNCTION(GetMetatypeMetadata, swift_getMetatypeMetadata, C_CC,
650663
RETURNS(TypeMetadataPtrTy),

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3685,7 +3685,7 @@ llvm::StructType *IRGenModule::getGenericWitnessTableCacheTy() {
36853685
{
36863686
// WitnessTableSizeInWords
36873687
Int16Ty,
3688-
// WitnessTablePrivateSizeInWords
3688+
// WitnessTablePrivateSizeInWords + RequiresInstantiation bit
36893689
Int16Ty,
36903690
// Protocol
36913691
RelativeAddressTy,
@@ -3804,27 +3804,6 @@ IRGenModule::getAddrOfWitnessTablePattern(const NormalProtocolConformance *conf,
38043804
WitnessTableTy, DebugTypeInfo());
38053805
}
38063806

3807-
llvm::Function *
3808-
IRGenModule::getAddrOfAssociatedTypeMetadataAccessFunction(
3809-
const NormalProtocolConformance *conformance,
3810-
AssociatedType association) {
3811-
auto forDefinition = ForDefinition;
3812-
3813-
LinkEntity entity =
3814-
LinkEntity::forAssociatedTypeMetadataAccessFunction(conformance,
3815-
association);
3816-
llvm::Function *&entry = GlobalFuncs[entity];
3817-
if (entry) {
3818-
if (forDefinition) updateLinkageForDefinition(*this, entry, entity);
3819-
return entry;
3820-
}
3821-
3822-
auto signature = getAssociatedTypeMetadataAccessFunctionSignature();
3823-
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
3824-
entry = createFunction(*this, link, signature);
3825-
return entry;
3826-
}
3827-
38283807
llvm::Function *
38293808
IRGenModule::getAddrOfAssociatedTypeWitnessTableAccessFunction(
38303809
const NormalProtocolConformance *conformance,
@@ -3846,25 +3825,6 @@ IRGenModule::getAddrOfAssociatedTypeWitnessTableAccessFunction(
38463825
return entry;
38473826
}
38483827

3849-
llvm::Function *
3850-
IRGenModule::getAddrOfDefaultAssociatedTypeMetadataAccessFunction(
3851-
AssociatedType association) {
3852-
auto forDefinition = ForDefinition;
3853-
3854-
LinkEntity entity =
3855-
LinkEntity::forDefaultAssociatedTypeMetadataAccessFunction(association);
3856-
llvm::Function *&entry = GlobalFuncs[entity];
3857-
if (entry) {
3858-
if (forDefinition) updateLinkageForDefinition(*this, entry, entity);
3859-
return entry;
3860-
}
3861-
3862-
auto signature = getAssociatedTypeMetadataAccessFunctionSignature();
3863-
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
3864-
entry = createFunction(*this, link, signature);
3865-
return entry;
3866-
}
3867-
38683828
llvm::Function *
38693829
IRGenModule::getAddrOfDefaultAssociatedConformanceAccessor(
38703830
AssociatedConformance requirement) {

lib/IRGen/GenMeta.cpp

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,8 @@ namespace {
457457

458458
void addExtendedContext() {
459459
auto string = IGM.getTypeRef(
460-
E->getSelfInterfaceType()->getCanonicalType());
460+
E->getSelfInterfaceType()->getCanonicalType(),
461+
MangledTypeRefRole::Metadata);
461462
B.addRelativeAddress(string);
462463
}
463464

@@ -602,7 +603,6 @@ namespace {
602603
auto var = cast<llvm::GlobalVariable>(addr);
603604

604605
var->setConstant(true);
605-
disableAddressSanitizer(IGM, var);
606606
IGM.setTrueConstGlobal(var);
607607
}
608608

@@ -765,51 +765,16 @@ namespace {
765765
entry.getAssociatedTypeWitness().Requirement != assocType)
766766
continue;
767767

768-
auto witness = entry.getAssociatedTypeWitness().Witness;
769-
return getDefaultAssociatedTypeMetadataAccessFunction(
770-
AssociatedType(assocType), witness);
768+
auto witness =
769+
entry.getAssociatedTypeWitness().Witness->mapTypeOutOfContext()
770+
->getCanonicalType();
771+
return IGM.getAssociatedTypeWitness(witness,
772+
/*inProtocolContext=*/true);
771773
}
772774

773775
return nullptr;
774776
}
775777

776-
/// Create an associated type metadata access function for the default
777-
/// associated type witness.
778-
llvm::Constant *getDefaultAssociatedTypeMetadataAccessFunction(
779-
AssociatedType requirement, CanType witness) {
780-
auto accessor =
781-
IGM.getAddrOfDefaultAssociatedTypeMetadataAccessFunction(requirement);
782-
783-
IRGenFunction IGF(IGM, accessor);
784-
if (IGM.DebugInfo)
785-
IGM.DebugInfo->emitArtificialFunction(IGF, accessor);
786-
787-
Explosion parameters = IGF.collectParameters();
788-
auto request = DynamicMetadataRequest(parameters.claimNext());
789-
790-
llvm::Value *self = parameters.claimNext();
791-
llvm::Value *wtable = parameters.claimNext();
792-
793-
CanType selfInContext =
794-
Proto->mapTypeIntoContext(Proto->getProtocolSelfType())
795-
->getCanonicalType();
796-
797-
// Bind local Self type data from the metadata argument.
798-
IGF.bindLocalTypeDataFromTypeMetadata(selfInContext, IsExact, self,
799-
MetadataState::Abstract);
800-
IGF.setUnscopedLocalTypeData(
801-
selfInContext,
802-
LocalTypeDataKind::forAbstractProtocolWitnessTable(Proto),
803-
wtable);
804-
805-
// Emit a reference to the type metadata.
806-
auto response = IGF.emitTypeMetadataRef(witness, request);
807-
response.ensureDynamicState(IGF);
808-
auto returnValue = response.combine(IGF);
809-
IGF.Builder.CreateRet(returnValue);
810-
return accessor;
811-
}
812-
813778
llvm::Constant *findDefaultAssociatedConformanceWitness(
814779
CanType association,
815780
ProtocolDecl *requirement) {
@@ -4237,7 +4202,8 @@ GenericRequirementsMetadata irgen::addGenericRequirements(
42374202

42384203
auto flags = GenericRequirementFlags(abiKind, false, false);
42394204
auto typeName =
4240-
IGM.getTypeRef(requirement.getSecondType()->getCanonicalType());
4205+
IGM.getTypeRef(requirement.getSecondType()->getCanonicalType(),
4206+
MangledTypeRefRole::Metadata);
42414207

42424208
addGenericRequirement(IGM, B, metadata, sig, flags,
42434209
requirement.getFirstType(),

0 commit comments

Comments
 (0)