Skip to content

Commit a0e3258

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.
1 parent e089f2a commit a0e3258

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
@@ -84,7 +84,7 @@ Globals
8484
global ::= protocol-conformance 'WP' // protocol witness table
8585
global ::= protocol-conformance 'Wa' // protocol witness table accessor
8686

87-
global ::= protocol-conformance 'WG' // generic protocol witness table
87+
global ::= protocol-conformance 'WG' // generic protocol witness table (HISTORICAL)
8888
global ::= protocol-conformance 'Wp' // protocol witness table pattern
8989
global ::= protocol-conformance 'Wr' // resilient witness table (HISTORICAL)
9090
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
@@ -247,10 +247,6 @@ class LinkEntity {
247247
/// ProtocolConformance*.
248248
ProtocolWitnessTableAccessFunction,
249249

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

741-
static LinkEntity
742-
forGenericProtocolWitnessTableCache(const ProtocolConformance *C) {
743-
LinkEntity entity;
744-
entity.setForProtocolConformance(Kind::GenericProtocolWitnessTableCache, C);
745-
return entity;
746-
}
747-
748737
static LinkEntity
749738
forGenericProtocolWitnessTableInstantiationFunction(
750739
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
@@ -3644,15 +3644,6 @@ IRGenModule::getResilienceExpansionForLayout(SILGlobalVariable *global) {
36443644
return ResilienceExpansion::Maximal;
36453645
}
36463646

3647-
llvm::Constant *IRGenModule::
3648-
getAddrOfGenericWitnessTableCache(const NormalProtocolConformance *conf,
3649-
ForDefinition_t forDefinition) {
3650-
auto entity = LinkEntity::forGenericProtocolWitnessTableCache(conf);
3651-
auto expectedTy = getGenericWitnessTableCacheTy();
3652-
return getAddrOfLLVMVariable(entity, getPointerAlignment(), forDefinition,
3653-
expectedTy, DebugTypeInfo());
3654-
}
3655-
36563647
llvm::Function *
36573648
IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction(
36583649
const NormalProtocolConformance *conf) {
@@ -3675,25 +3666,6 @@ IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction(
36753666
return entry;
36763667
}
36773668

3678-
llvm::StructType *IRGenModule::getGenericWitnessTableCacheTy() {
3679-
if (auto ty = GenericWitnessTableCacheTy) return ty;
3680-
3681-
GenericWitnessTableCacheTy = llvm::StructType::create(getLLVMContext(),
3682-
{
3683-
// WitnessTableSizeInWords
3684-
Int16Ty,
3685-
// WitnessTablePrivateSizeInWords + RequiresInstantiation bit
3686-
Int16Ty,
3687-
// Pattern
3688-
RelativeAddressTy,
3689-
// Instantiator
3690-
RelativeAddressTy,
3691-
// PrivateData
3692-
RelativeAddressTy
3693-
}, "swift.generic_witness_table_cache");
3694-
return GenericWitnessTableCacheTy;
3695-
}
3696-
36973669
/// Fetch the witness table access function for a protocol conformance.
36983670
llvm::Function *
36993671
IRGenModule::getAddrOfWitnessTableAccessFunction(

0 commit comments

Comments
 (0)