@@ -145,13 +145,40 @@ Metadata *TargetSingletonMetadataInitialization<InProcess>::allocate(
145
145
static void installGenericArguments (Metadata *metadata,
146
146
const TypeContextDescriptor *description,
147
147
const void *arguments) {
148
- auto &generics = description->getFullGenericContextHeader ();
148
+ const auto &genericContext = *description->getGenericContext ();
149
+ const auto &header = genericContext.getGenericContextHeader ();
149
150
150
- // FIXME: variadic-parameter-packs
151
- memcpy ( reinterpret_cast < const void **>(metadata)
152
- + description-> getGenericArgumentOffset () ,
151
+ auto dst = ( reinterpret_cast < const void **>(metadata) +
152
+ description-> getGenericArgumentOffset ());
153
+ memcpy (dst ,
153
154
reinterpret_cast <const void * const *>(arguments),
154
- generics.Base .getNumArguments () * sizeof (void *));
155
+ header.NumKeyArguments * sizeof (void *));
156
+
157
+ // If we don't have any pack arguments, there is nothing more to do.
158
+ auto packShapeHeader = genericContext.getGenericPackShapeHeader ();
159
+ if (packShapeHeader.NumPacks == 0 )
160
+ return ;
161
+
162
+ // Heap-allocate all installed metadata and witness table packs.
163
+ for (auto pack : genericContext.getGenericPackShapeDescriptors ()) {
164
+ assert (pack.ShapeClass < packShapeHeader.NumShapeClasses );
165
+
166
+ size_t count = reinterpret_cast <size_t >(dst[pack.ShapeClass ]);
167
+
168
+ switch (pack.Kind ) {
169
+ case GenericPackKind::Metadata:
170
+ dst[pack.Index ] = swift_allocateMetadataPack (
171
+ reinterpret_cast <const Metadata * const *>(dst[pack.Index ]),
172
+ count);
173
+ break ;
174
+
175
+ case GenericPackKind::WitnessTable:
176
+ dst[pack.Index ] = swift_allocateWitnessTablePack (
177
+ reinterpret_cast <const WitnessTable * const *>(dst[pack.Index ]),
178
+ count);
179
+ break ;
180
+ }
181
+ }
155
182
}
156
183
157
184
#if SWIFT_OBJC_INTEROP
@@ -1154,7 +1181,7 @@ namespace {
1154
1181
1155
1182
class MetadataPackCacheEntry {
1156
1183
public:
1157
- unsigned Count;
1184
+ size_t Count;
1158
1185
1159
1186
const Metadata * const * getElements () const {
1160
1187
return reinterpret_cast <const Metadata * const *>(this + 1 );
@@ -1166,20 +1193,20 @@ class MetadataPackCacheEntry {
1166
1193
1167
1194
struct Key {
1168
1195
const Metadata *const *Data;
1169
- const unsigned Count;
1196
+ const size_t Count;
1170
1197
1171
- unsigned getCount () const {
1198
+ size_t getCount () const {
1172
1199
return Count;
1173
1200
}
1174
1201
1175
- const Metadata *getElement (unsigned index) const {
1202
+ const Metadata *getElement (size_t index) const {
1176
1203
assert (index < Count);
1177
1204
return Data[index];
1178
1205
}
1179
1206
1180
1207
friend llvm::hash_code hash_value (const Key &key) {
1181
1208
llvm::hash_code hash = 0 ;
1182
- for (unsigned i = 0 ; i != key.getCount (); ++i)
1209
+ for (size_t i = 0 ; i != key.getCount (); ++i)
1183
1210
hash = llvm::hash_combine (hash, key.getElement (i));
1184
1211
return hash;
1185
1212
}
@@ -1202,7 +1229,10 @@ class MetadataPackCacheEntry {
1202
1229
}
1203
1230
1204
1231
friend llvm::hash_code hash_value (const MetadataPackCacheEntry &value) {
1205
- return hash_value (value.getElements ());
1232
+ llvm::hash_code hash = 0 ;
1233
+ for (size_t i = 0 ; i != value.Count ; ++i)
1234
+ hash = llvm::hash_combine (hash, value.getElements ()[i]);
1235
+ return hash;
1206
1236
}
1207
1237
1208
1238
static size_t getExtraAllocationSize (const Key &key) {
@@ -1219,9 +1249,9 @@ class MetadataPackCacheEntry {
1219
1249
};
1220
1250
1221
1251
MetadataPackCacheEntry::MetadataPackCacheEntry (const Key &key) {
1222
- auto count = key.getCount ();
1252
+ Count = key.getCount ();
1223
1253
1224
- for (unsigned i = 0 ; i < count ; ++i)
1254
+ for (unsigned i = 0 ; i < Count ; ++i)
1225
1255
getElements ()[i] = key.getElement (i);
1226
1256
}
1227
1257
@@ -1232,7 +1262,7 @@ static SimpleGlobalCache<MetadataPackCacheEntry, MetadataPackTag> MetadataPacks;
1232
1262
1233
1263
SWIFT_RUNTIME_EXPORT SWIFT_CC (swift)
1234
1264
const Metadata * const *
1235
- swift_allocateMetadataPack(const Metadata * const *ptr, unsigned count) {
1265
+ swift_allocateMetadataPack(const Metadata * const *ptr, size_t count) {
1236
1266
if (MetadataPackPointer (reinterpret_cast <uintptr_t >(ptr)).getLifetime ()
1237
1267
== PackLifetime::OnHeap)
1238
1268
return ptr;
@@ -1245,7 +1275,7 @@ swift_allocateMetadataPack(const Metadata * const *ptr, unsigned count) {
1245
1275
1246
1276
SWIFT_RUNTIME_EXPORT SWIFT_CC (swift)
1247
1277
const WitnessTable * const *
1248
- swift_allocateWitnessTablePack(const WitnessTable * const *ptr, unsigned count) {
1278
+ swift_allocateWitnessTablePack(const WitnessTable * const *ptr, size_t count) {
1249
1279
if (WitnessTablePackPointer (reinterpret_cast <uintptr_t >(ptr)).getLifetime ()
1250
1280
== PackLifetime::OnHeap)
1251
1281
return ptr;
@@ -6513,13 +6543,54 @@ static bool findAnyTransitiveMetadata(const Metadata *type, T &&predicate) {
6513
6543
6514
6544
// Generic types require their type arguments to be transitively complete.
6515
6545
if (description->isGeneric ()) {
6546
+ auto *genericContext = description->getGenericContext ();
6547
+
6516
6548
auto keyArguments = description->getGenericArguments (type);
6517
- for (auto ¶m : description->getGenericParams ()) {
6518
- if (param.hasKeyArgument ()) {
6519
- if (predicate (*keyArguments++))
6549
+
6550
+ // The generic argument area begins with a pack count for each
6551
+ // shape class; skip them first.
6552
+ auto header = genericContext->getGenericPackShapeHeader ();
6553
+ unsigned paramIdx = header.NumShapeClasses ;
6554
+
6555
+ auto packs = genericContext->getGenericPackShapeDescriptors ();
6556
+ unsigned packIdx = 0 ;
6557
+ for (auto ¶m : genericContext->getGenericParams ()) {
6558
+ // Ignore parameters that don't have a key argument.
6559
+ if (!param.hasKeyArgument ())
6560
+ continue ;
6561
+
6562
+ switch (param.getKind ()) {
6563
+ case GenericParamKind::Type:
6564
+ if (predicate (keyArguments[paramIdx]))
6520
6565
return true ;
6566
+
6567
+ break ;
6568
+
6569
+ case GenericParamKind::TypePack: {
6570
+ assert (packIdx < header.NumPacks );
6571
+ assert (packs[packIdx].Kind == GenericPackKind::Metadata);
6572
+ assert (packs[packIdx].Index == paramIdx);
6573
+ assert (packs[packIdx].ShapeClass < header.NumShapeClasses );
6574
+
6575
+ MetadataPackPointer pack (keyArguments[paramIdx]);
6576
+ assert (pack.getLifetime () == PackLifetime::OnHeap);
6577
+
6578
+ uintptr_t count = reinterpret_cast <uintptr_t >(
6579
+ keyArguments[packs[packIdx].ShapeClass ]);
6580
+ for (uintptr_t j = 0 ; j < count; ++j) {
6581
+ if (predicate (pack.getElements ()[j]))
6582
+ return true ;
6583
+ }
6584
+
6585
+ ++packIdx;
6586
+ break ;
6521
6587
}
6522
- // Ignore parameters that don't have a key argument.
6588
+
6589
+ default :
6590
+ llvm_unreachable (" Unsupported generic parameter kind" );
6591
+ }
6592
+
6593
+ ++paramIdx;
6523
6594
}
6524
6595
}
6525
6596
0 commit comments