Skip to content

Commit 7059bdc

Browse files
committed
[ABI] Collapse generic witness table into protocol conformance record.
Collapse the generic witness table, which was used only as a uniquing data structure during witness table instantiation, into the protocol conformance record. This colocates all of the constant protocol conformance metadata and makes it possible for us to recover the generic witness table from the conformance descriptor (including looking at the pattern itself). Rename swift_getGenericWitnessTable() to swift_instantiateWitnessTable() to make it clearer what its purpose is, and take the conformance descriptor directly. (cherry picked from commit a0e3258)
1 parent e1e0194 commit 7059bdc

20 files changed

+264
-388
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Globals
130130
global ::= protocol-conformance 'WP' // protocol witness table
131131
global ::= protocol-conformance 'Wa' // protocol witness table accessor
132132

133-
global ::= protocol-conformance 'WG' // generic protocol witness table
133+
global ::= protocol-conformance 'WG' // generic protocol witness table (HISTORICAL)
134134
global ::= protocol-conformance 'Wp' // protocol witness table pattern
135135
global ::= protocol-conformance 'Wr' // resilient witness table (HISTORICAL)
136136
global ::= protocol-conformance 'WI' // generic protocol witness table instantiation function

include/swift/ABI/Metadata.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,7 +1989,7 @@ struct TargetResilientWitnessTable final
19891989
using ResilientWitnessTable = TargetResilientWitnessTable<InProcess>;
19901990

19911991
/// \brief The control structure of a generic or resilient protocol
1992-
/// conformance.
1992+
/// conformance, which is embedded in the protocol conformance descriptor.
19931993
///
19941994
/// Witness tables need to be instantiated at runtime in these cases:
19951995
/// - For a generic conforming type, associated type requirements might be
@@ -2245,14 +2245,16 @@ struct TargetProtocolConformanceDescriptor final
22452245
RelativeContextPointer<Runtime>,
22462246
TargetGenericRequirementDescriptor<Runtime>,
22472247
TargetResilientWitnessesHeader<Runtime>,
2248-
TargetResilientWitness<Runtime>> {
2248+
TargetResilientWitness<Runtime>,
2249+
TargetGenericWitnessTable<Runtime>> {
22492250

22502251
using TrailingObjects = swift::ABI::TrailingObjects<
22512252
TargetProtocolConformanceDescriptor<Runtime>,
22522253
RelativeContextPointer<Runtime>,
22532254
TargetGenericRequirementDescriptor<Runtime>,
22542255
TargetResilientWitnessesHeader<Runtime>,
2255-
TargetResilientWitness<Runtime>>;
2256+
TargetResilientWitness<Runtime>,
2257+
TargetGenericWitnessTable<Runtime>>;
22562258
friend TrailingObjects;
22572259

22582260
template<typename T>
@@ -2268,6 +2270,7 @@ struct TargetProtocolConformanceDescriptor final
22682270

22692271
using ResilientWitnessesHeader = TargetResilientWitnessesHeader<Runtime>;
22702272
using ResilientWitness = TargetResilientWitness<Runtime>;
2273+
using GenericWitnessTable = TargetGenericWitnessTable<Runtime>;
22712274

22722275
private:
22732276
/// The protocol being conformed to.
@@ -2375,6 +2378,14 @@ struct TargetProtocolConformanceDescriptor final
23752378
numTrailingObjects(OverloadToken<ResilientWitness>()));
23762379
}
23772380

2381+
ConstTargetPointer<Runtime, GenericWitnessTable>
2382+
getGenericWitnessTable() const {
2383+
if (!Flags.hasGenericWitnessTable())
2384+
return nullptr;
2385+
2386+
return this->template getTrailingObjects<GenericWitnessTable>();
2387+
}
2388+
23782389
#if !defined(NDEBUG) && SWIFT_OBJC_INTEROP
23792390
void dump() const;
23802391
#endif
@@ -2409,6 +2420,10 @@ struct TargetProtocolConformanceDescriptor final
24092420
->NumWitnesses
24102421
: 0;
24112422
}
2423+
2424+
size_t numTrailingObjects(OverloadToken<GenericWitnessTable>) const {
2425+
return Flags.hasGenericWitnessTable() ? 1 : 0;
2426+
}
24122427
};
24132428
using ProtocolConformanceDescriptor
24142429
= TargetProtocolConformanceDescriptor<InProcess>;

include/swift/ABI/MetadataValues.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ class ConformanceFlags {
629629
NumConditionalRequirementsShift = 8,
630630

631631
HasResilientWitnessesMask = 0x01 << 16,
632+
HasGenericWitnessTableMask = 0x01 << 17,
632633
};
633634

634635
int_type Value;
@@ -668,6 +669,14 @@ class ConformanceFlags {
668669
: 0));
669670
}
670671

672+
ConformanceFlags withHasGenericWitnessTable(
673+
bool hasGenericWitnessTable) const {
674+
return ConformanceFlags((Value & ~HasGenericWitnessTableMask)
675+
| (hasGenericWitnessTable
676+
? HasGenericWitnessTableMask
677+
: 0));
678+
}
679+
671680
/// Retrieve the conformance kind.
672681
ConformanceKind getConformanceKind() const {
673682
return ConformanceKind(Value & ConformanceKindMask);
@@ -709,6 +718,12 @@ class ConformanceFlags {
709718
return Value & HasResilientWitnessesMask;
710719
}
711720

721+
/// Whether this conformance has a generic witness table that may need to
722+
/// be instantiated.
723+
bool hasGenericWitnessTable() const {
724+
return Value & HasGenericWitnessTableMask;
725+
}
726+
712727
int_type getIntValue() const { return Value; }
713728
};
714729

include/swift/IRGen/Linking.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,6 @@ class LinkEntity {
248248
/// ProtocolConformance*.
249249
ProtocolWitnessTableAccessFunction,
250250

251-
/// A generic protocol witness table cache. The secondary pointer is a
252-
/// ProtocolConformance*.
253-
GenericProtocolWitnessTableCache,
254-
255251
/// The instantiation function for a generic protocol witness table.
256252
/// The secondary pointer is a ProtocolConformance*.
257253
GenericProtocolWitnessTableInstantiationFunction,
@@ -739,13 +735,6 @@ class LinkEntity {
739735
return entity;
740736
}
741737

742-
static LinkEntity
743-
forGenericProtocolWitnessTableCache(const ProtocolConformance *C) {
744-
LinkEntity entity;
745-
entity.setForProtocolConformance(Kind::GenericProtocolWitnessTableCache, C);
746-
return entity;
747-
}
748-
749738
static LinkEntity
750739
forGenericProtocolWitnessTableInstantiationFunction(
751740
const ProtocolConformance *C) {

include/swift/Runtime/Metadata.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,10 +387,10 @@ MetadataResponse swift_checkMetadataState(MetadataRequest request,
387387

388388
/// Instantiate a resilient or generic protocol witness table.
389389
///
390-
/// \param genericTable - The witness table template for the
391-
/// conformance. It may either have fields that require runtime
392-
/// initialization, or be missing requirements at the end for
393-
/// which default witnesses are available.
390+
/// \param conformance - The protocol conformance descriptor, which
391+
/// contains the generic witness table record. It may either have fields
392+
/// that require runtime initialization, or be missing requirements at the
393+
/// end for which default witnesses are available.
394394
///
395395
/// \param type - The conforming type, used to form a uniquing key
396396
/// for the conformance. If the witness table is not dependent on
@@ -406,9 +406,9 @@ MetadataResponse swift_checkMetadataState(MetadataRequest request,
406406
/// conformances.
407407
SWIFT_RUNTIME_EXPORT
408408
const WitnessTable *
409-
swift_getGenericWitnessTable(GenericWitnessTable *genericTable,
410-
const Metadata *type,
411-
void **const *instantiationArgs);
409+
swift_instantiateWitnessTable(ProtocolConformanceDescriptor *conformance,
410+
const Metadata *type,
411+
void **const *instantiationArgs);
412412

413413
/// Retrieve an associated type witness from the given witness table.
414414
///

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -635,12 +635,12 @@ FUNCTION(CheckMetadataState, swift_checkMetadataState, SwiftCC,
635635
ATTRS(NoUnwind, ReadOnly))
636636

637637
// const ProtocolWitnessTable *
638-
// swift_getGenericWitnessTable(GenericProtocolWitnessTable *genericTable,
639-
// const Metadata *type,
640-
// void ** const *instantiationArgs);
641-
FUNCTION(GetGenericWitnessTable, swift_getGenericWitnessTable, C_CC,
638+
// swift_instantiateWitnessTable(const ProtocolConformanceDescriptor *conf,
639+
// const Metadata *type,
640+
// void ** const *instantiationArgs);
641+
FUNCTION(InstantiateWitnessTable, swift_instantiateWitnessTable, C_CC,
642642
RETURNS(WitnessTablePtrTy),
643-
ARGS(getGenericWitnessTableCacheTy()->getPointerTo(),
643+
ARGS(ProtocolConformanceDescriptorPtrTy,
644644
TypeMetadataPtrTy,
645645
WitnessTablePtrPtrTy),
646646
ATTRS(NoUnwind, ReadOnly))

lib/IRGen/GenDecl.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3619,15 +3619,6 @@ IRGenModule::getResilienceExpansionForLayout(SILGlobalVariable *global) {
36193619
return ResilienceExpansion::Maximal;
36203620
}
36213621

3622-
llvm::Constant *IRGenModule::
3623-
getAddrOfGenericWitnessTableCache(const NormalProtocolConformance *conf,
3624-
ForDefinition_t forDefinition) {
3625-
auto entity = LinkEntity::forGenericProtocolWitnessTableCache(conf);
3626-
auto expectedTy = getGenericWitnessTableCacheTy();
3627-
return getAddrOfLLVMVariable(entity, getPointerAlignment(), forDefinition,
3628-
expectedTy, DebugTypeInfo());
3629-
}
3630-
36313622
llvm::Function *
36323623
IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction(
36333624
const NormalProtocolConformance *conf) {
@@ -3650,25 +3641,6 @@ IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction(
36503641
return entry;
36513642
}
36523643

3653-
llvm::StructType *IRGenModule::getGenericWitnessTableCacheTy() {
3654-
if (auto ty = GenericWitnessTableCacheTy) return ty;
3655-
3656-
GenericWitnessTableCacheTy = llvm::StructType::create(getLLVMContext(),
3657-
{
3658-
// WitnessTableSizeInWords
3659-
Int16Ty,
3660-
// WitnessTablePrivateSizeInWords + RequiresInstantiation bit
3661-
Int16Ty,
3662-
// Pattern
3663-
RelativeAddressTy,
3664-
// Instantiator
3665-
RelativeAddressTy,
3666-
// PrivateData
3667-
RelativeAddressTy
3668-
}, "swift.generic_witness_table_cache");
3669-
return GenericWitnessTableCacheTy;
3670-
}
3671-
36723644
/// Fetch the witness table access function for a protocol conformance.
36733645
llvm::Function *
36743646
IRGenModule::getAddrOfWitnessTableAccessFunction(

0 commit comments

Comments
 (0)