Skip to content

Commit 09c72e2

Browse files
authored
Merge pull request #18334 from rjmccall/foreign-metadata-initialization
Update the ABI for uniquing foreign type metadata
2 parents cef8284 + db8f23d commit 09c72e2

20 files changed

+703
-677
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
@@ -1268,6 +1268,10 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
12681268
/// "in-place" code pattern.
12691269
InPlaceMetadataInitialization = 1,
12701270

1271+
/// The type requires non-trivial singleton initialization using the
1272+
/// "foreign" code pattern.
1273+
ForeignMetadataInitialization = 2,
1274+
12711275
// We only have two bits here, so if you add a third special kind,
12721276
// include more flag bits in its out-of-line storage.
12731277
};
@@ -1282,6 +1286,10 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
12821286
return getMetadataInitialization() == InPlaceMetadataInitialization;
12831287
}
12841288

1289+
bool hasForeignMetadataInitialization() const {
1290+
return getMetadataInitialization() == ForeignMetadataInitialization;
1291+
}
1292+
12851293
enum ImportNamespaceKind {
12861294
/// The type comes the default namespace for its language.
12871295
DefaultNamespace = 0,

include/swift/Remote/MetadataReader.h

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,8 +1188,22 @@ class MetadataReader {
11881188
TypeContextDescriptorFlags typeFlags(flags.getKindSpecificFlags());
11891189
unsigned baseSize = 0;
11901190
unsigned genericHeaderSize = sizeof(GenericContextDescriptorHeader);
1191-
unsigned inPlaceInitSize = 0;
1191+
unsigned metadataInitSize = 0;
11921192
bool hasVTable = false;
1193+
1194+
auto readMetadataInitSize = [&]() -> unsigned {
1195+
switch (typeFlags.getMetadataInitialization()) {
1196+
case TypeContextDescriptorFlags::NoMetadataInitialization:
1197+
return 0;
1198+
case TypeContextDescriptorFlags::InPlaceMetadataInitialization:
1199+
// FIXME: classes
1200+
return sizeof(TargetInPlaceValueMetadataInitialization<Runtime>);
1201+
case TypeContextDescriptorFlags::ForeignMetadataInitialization:
1202+
return sizeof(TargetForeignMetadataInitialization<Runtime>);
1203+
}
1204+
return 0;
1205+
};
1206+
11931207
switch (auto kind = flags.getKind()) {
11941208
case ContextDescriptorKind::Module:
11951209
baseSize = sizeof(TargetModuleContextDescriptor<Runtime>);
@@ -1205,22 +1219,17 @@ class MetadataReader {
12051219
baseSize = sizeof(TargetClassDescriptor<Runtime>);
12061220
genericHeaderSize = sizeof(TypeGenericContextDescriptorHeader);
12071221
hasVTable = typeFlags.class_hasVTable();
1222+
metadataInitSize = readMetadataInitSize();
12081223
break;
12091224
case ContextDescriptorKind::Enum:
12101225
baseSize = sizeof(TargetEnumDescriptor<Runtime>);
12111226
genericHeaderSize = sizeof(TypeGenericContextDescriptorHeader);
1212-
if (typeFlags.hasInPlaceMetadataInitialization()) {
1213-
inPlaceInitSize =
1214-
sizeof(TargetInPlaceValueMetadataInitialization<Runtime>);
1215-
}
1227+
metadataInitSize = readMetadataInitSize();
12161228
break;
12171229
case ContextDescriptorKind::Struct:
12181230
baseSize = sizeof(TargetStructDescriptor<Runtime>);
12191231
genericHeaderSize = sizeof(TypeGenericContextDescriptorHeader);
1220-
if (typeFlags.hasInPlaceMetadataInitialization()) {
1221-
inPlaceInitSize =
1222-
sizeof(TargetInPlaceValueMetadataInitialization<Runtime>);
1223-
}
1232+
metadataInitSize = readMetadataInitSize();
12241233
break;
12251234
case ContextDescriptorKind::Protocol:
12261235
baseSize = sizeof(TargetProtocolDescriptorRef<Runtime>);
@@ -1229,7 +1238,7 @@ class MetadataReader {
12291238
// We don't know about this kind of context.
12301239
return nullptr;
12311240
}
1232-
1241+
12331242
// Determine the full size of the descriptor. This is reimplementing a fair
12341243
// bit of TrailingObjects but for out-of-process; maybe there's a way to
12351244
// factor the layout stuff out...
@@ -1256,7 +1265,8 @@ class MetadataReader {
12561265
TargetVTableDescriptorHeader<Runtime> header;
12571266
auto headerAddr = address
12581267
+ baseSize
1259-
+ genericsSize;
1268+
+ genericsSize
1269+
+ metadataInitSize;
12601270

12611271
if (!Reader->readBytes(RemoteAddress(headerAddr),
12621272
(uint8_t*)&header, sizeof(header)))
@@ -1266,7 +1276,7 @@ class MetadataReader {
12661276
+ header.VTableSize * sizeof(TargetMethodDescriptor<Runtime>);
12671277
}
12681278

1269-
unsigned size = baseSize + genericsSize + vtableSize + inPlaceInitSize;
1279+
unsigned size = baseSize + genericsSize + metadataInitSize + vtableSize;
12701280
auto buffer = (uint8_t *)malloc(size);
12711281
if (!Reader->readBytes(RemoteAddress(address), buffer, size)) {
12721282
free(buffer);

include/swift/Runtime/Metadata.h

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

471471
/// \brief Fetch a unique type metadata object for a foreign type.
472-
SWIFT_RUNTIME_EXPORT
473-
const ForeignTypeMetadata *
474-
swift_getForeignTypeMetadata(ForeignTypeMetadata *nonUnique);
472+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
473+
MetadataResponse
474+
swift_getForeignTypeMetadata(MetadataRequest request,
475+
ForeignTypeMetadata *nonUnique);
475476

476477
/// \brief Fetch a unique witness table for a foreign witness table.
477478
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(

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)