Skip to content

Commit ce23fd4

Browse files
committed
Update the ABI for uniquing foreign type metadata.
- `swift_getForeignTypeMetadata` is now a request/response function. - The initialization function is now a completion function, and the pointer to it has moved into the type descriptor. - The cache variable is no longer part of the ABI; it's an implementation detail of the access function. - The two points above mean that there is no special header on foreign type metadata and therefore that they can be marked constant when there isn't something about them that needs to be initialized. The only foreign-metadata initialization we actually do right now is of the superclass field of a foreign class, and since that relationship is a proper DAG, it's not actually possible to have recursive initialization problems. But this is the right long-term thing to do, and it removes one of the last two clients of once-based initialization.
1 parent 80b5ab8 commit ce23fd4

20 files changed

+704
-678
lines changed

include/swift/ABI/Metadata.h

Lines changed: 97 additions & 144 deletions
Large diffs are not rendered by default.

include/swift/ABI/MetadataValues.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,10 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
12621262
/// "in-place" code pattern.
12631263
InPlaceMetadataInitialization = 1,
12641264

1265+
/// The type requires non-trivial singleton initialization using the
1266+
/// "foreign" code pattern.
1267+
ForeignMetadataInitialization = 2,
1268+
12651269
// We only have two bits here, so if you add a third special kind,
12661270
// include more flag bits in its out-of-line storage.
12671271
};
@@ -1276,6 +1280,10 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
12761280
return getMetadataInitialization() == InPlaceMetadataInitialization;
12771281
}
12781282

1283+
bool hasForeignMetadataInitialization() const {
1284+
return getMetadataInitialization() == ForeignMetadataInitialization;
1285+
}
1286+
12791287
enum ImportNamespaceKind {
12801288
/// The type comes the default namespace for its language.
12811289
DefaultNamespace = 0,

include/swift/Remote/MetadataReader.h

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,8 +1050,22 @@ class MetadataReader {
10501050
TypeContextDescriptorFlags typeFlags(flags.getKindSpecificFlags());
10511051
unsigned baseSize = 0;
10521052
unsigned genericHeaderSize = sizeof(GenericContextDescriptorHeader);
1053-
unsigned inPlaceInitSize = 0;
1053+
unsigned metadataInitSize = 0;
10541054
bool hasVTable = false;
1055+
1056+
auto readMetadataInitSize = [&]() -> unsigned {
1057+
switch (typeFlags.getMetadataInitialization()) {
1058+
case TypeContextDescriptorFlags::NoMetadataInitialization:
1059+
return 0;
1060+
case TypeContextDescriptorFlags::InPlaceMetadataInitialization:
1061+
// FIXME: classes
1062+
return sizeof(TargetInPlaceValueMetadataInitialization<Runtime>);
1063+
case TypeContextDescriptorFlags::ForeignMetadataInitialization:
1064+
return sizeof(TargetForeignMetadataInitialization<Runtime>);
1065+
}
1066+
return 0;
1067+
};
1068+
10551069
switch (auto kind = flags.getKind()) {
10561070
case ContextDescriptorKind::Module:
10571071
baseSize = sizeof(TargetModuleContextDescriptor<Runtime>);
@@ -1067,28 +1081,23 @@ class MetadataReader {
10671081
baseSize = sizeof(TargetClassDescriptor<Runtime>);
10681082
genericHeaderSize = sizeof(TypeGenericContextDescriptorHeader);
10691083
hasVTable = typeFlags.class_hasVTable();
1084+
metadataInitSize = readMetadataInitSize();
10701085
break;
10711086
case ContextDescriptorKind::Enum:
10721087
baseSize = sizeof(TargetEnumDescriptor<Runtime>);
10731088
genericHeaderSize = sizeof(TypeGenericContextDescriptorHeader);
1074-
if (typeFlags.hasInPlaceMetadataInitialization()) {
1075-
inPlaceInitSize =
1076-
sizeof(TargetInPlaceValueMetadataInitialization<Runtime>);
1077-
}
1089+
metadataInitSize = readMetadataInitSize();
10781090
break;
10791091
case ContextDescriptorKind::Struct:
10801092
baseSize = sizeof(TargetStructDescriptor<Runtime>);
10811093
genericHeaderSize = sizeof(TypeGenericContextDescriptorHeader);
1082-
if (typeFlags.hasInPlaceMetadataInitialization()) {
1083-
inPlaceInitSize =
1084-
sizeof(TargetInPlaceValueMetadataInitialization<Runtime>);
1085-
}
1094+
metadataInitSize = readMetadataInitSize();
10861095
break;
10871096
default:
10881097
// We don't know about this kind of context.
10891098
return nullptr;
10901099
}
1091-
1100+
10921101
// Determine the full size of the descriptor. This is reimplementing a fair
10931102
// bit of TrailingObjects but for out-of-process; maybe there's a way to
10941103
// factor the layout stuff out...
@@ -1115,7 +1124,8 @@ class MetadataReader {
11151124
TargetVTableDescriptorHeader<Runtime> header;
11161125
auto headerAddr = address
11171126
+ baseSize
1118-
+ genericsSize;
1127+
+ genericsSize
1128+
+ metadataInitSize;
11191129

11201130
if (!Reader->readBytes(RemoteAddress(headerAddr),
11211131
(uint8_t*)&header, sizeof(header)))
@@ -1125,7 +1135,7 @@ class MetadataReader {
11251135
+ header.VTableSize * sizeof(TargetMethodDescriptor<Runtime>);
11261136
}
11271137

1128-
unsigned size = baseSize + genericsSize + vtableSize + inPlaceInitSize;
1138+
unsigned size = baseSize + genericsSize + metadataInitSize + vtableSize;
11291139
auto buffer = (uint8_t *)malloc(size);
11301140
if (!Reader->readBytes(RemoteAddress(address), buffer, size)) {
11311141
free(buffer);

include/swift/Runtime/Metadata.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,9 +475,10 @@ swift_getObjCClassFromObject(HeapObject *object);
475475
#endif
476476

477477
/// \brief Fetch a unique type metadata object for a foreign type.
478-
SWIFT_RUNTIME_EXPORT
479-
const ForeignTypeMetadata *
480-
swift_getForeignTypeMetadata(ForeignTypeMetadata *nonUnique);
478+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
479+
MetadataResponse
480+
swift_getForeignTypeMetadata(MetadataRequest request,
481+
ForeignTypeMetadata *nonUnique);
481482

482483
/// \brief Fetch a unique witness table for a foreign witness table.
483484
SWIFT_RUNTIME_EXPORT

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,9 @@ FUNCTION(GetFunctionMetadata3, swift_getFunctionTypeMetadata3,
638638
ATTRS(NoUnwind, ReadNone))
639639

640640
// Metadata *swift_getForeignTypeMetadata(Metadata *nonUnique);
641-
FUNCTION(GetForeignTypeMetadata, swift_getForeignTypeMetadata, C_CC,
642-
RETURNS(TypeMetadataPtrTy),
643-
ARGS(TypeMetadataPtrTy),
641+
FUNCTION(GetForeignTypeMetadata, swift_getForeignTypeMetadata, SwiftCC,
642+
RETURNS(TypeMetadataResponseTy),
643+
ARGS(SizeTy, TypeMetadataPtrTy),
644644
ATTRS(NoUnwind, ReadNone)) // only writes to runtime-private fields
645645

646646
// WitnessTable *swift_getForeignWitnessTable(const WitnessTable *candidate,

lib/IRGen/ForeignClassMetadataVisitor.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,8 @@ class ForeignClassMetadataVisitor
3737
void layout() {
3838
super::layout();
3939
asImpl().addNominalTypeDescriptor();
40-
asImpl().noteStartOfSuperClass();
4140
asImpl().addSuperclass();
4241
asImpl().addReservedWord();
43-
asImpl().addReservedWord();
44-
asImpl().addReservedWord();
45-
}
46-
47-
bool requiresInitializationFunction() {
48-
return Target->getSuperclassDecl() &&
49-
Target->getSuperclassDecl()->isForeign();
5042
}
5143

5244
CanType getTargetType() const {

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,8 +1488,7 @@ SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const {
14881488
return getSILLinkage(FormalLinkage::PublicUnique, forDefinition);
14891489

14901490
// Imported types.
1491-
if (getTypeMetadataAccessStrategy(type) ==
1492-
MetadataAccessStrategy::NonUniqueAccessor)
1491+
if (isAccessorLazilyGenerated(getTypeMetadataAccessStrategy(type)))
14931492
return SILLinkage::Shared;
14941493

14951494
// Everything else is only referenced inside its module.
@@ -1507,8 +1506,7 @@ SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const {
15071506
auto type = getType();
15081507

15091508
// Imported types, non-primitive structural types.
1510-
if (getTypeMetadataAccessStrategy(type) ==
1511-
MetadataAccessStrategy::NonUniqueAccessor)
1509+
if (isAccessorLazilyGenerated(getTypeMetadataAccessStrategy(type)))
15121510
return SILLinkage::Shared;
15131511

15141512
// Everything else is only referenced inside its module.
@@ -1548,6 +1546,7 @@ SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const {
15481546
return getSILLinkage(FormalLinkage::HiddenUnique, forDefinition);
15491547
case MetadataAccessStrategy::PrivateAccessor:
15501548
return getSILLinkage(FormalLinkage::Private, forDefinition);
1549+
case MetadataAccessStrategy::ForeignAccessor:
15511550
case MetadataAccessStrategy::NonUniqueAccessor:
15521551
return SILLinkage::Shared;
15531552
}

0 commit comments

Comments
 (0)