@@ -1146,6 +1146,119 @@ swift::swift_getObjCClassFromMetadataConditional(const Metadata *theMetadata) {
1146
1146
1147
1147
#endif
1148
1148
1149
+ /* **************************************************************************/
1150
+ /* ** Metadata and witness table packs **************************************/
1151
+ /* **************************************************************************/
1152
+
1153
+ namespace {
1154
+
1155
+ class MetadataPackCacheEntry {
1156
+ public:
1157
+ unsigned Count;
1158
+
1159
+ const Metadata * const * getElements () const {
1160
+ return reinterpret_cast <const Metadata * const *>(this + 1 );
1161
+ }
1162
+
1163
+ const Metadata ** getElements () {
1164
+ return reinterpret_cast <const Metadata **>(this + 1 );
1165
+ }
1166
+
1167
+ struct Key {
1168
+ const Metadata *const *Data;
1169
+ const unsigned Count;
1170
+
1171
+ unsigned getCount () const {
1172
+ return Count;
1173
+ }
1174
+
1175
+ const Metadata *getElement (unsigned index) const {
1176
+ assert (index < Count);
1177
+ return Data[index];
1178
+ }
1179
+
1180
+ friend llvm::hash_code hash_value (const Key &key) {
1181
+ llvm::hash_code hash = 0 ;
1182
+ for (unsigned i = 0 ; i != key.getCount (); ++i)
1183
+ hash = llvm::hash_combine (hash, key.getElement (i));
1184
+ return hash;
1185
+ }
1186
+ };
1187
+
1188
+ MetadataPackCacheEntry (const Key &key);
1189
+
1190
+ intptr_t getKeyIntValueForDump () {
1191
+ return 0 ; // No single meaningful value here.
1192
+ }
1193
+
1194
+ bool matchesKey (const Key &key) const {
1195
+ if (key.getCount () != Count)
1196
+ return false ;
1197
+ for (unsigned i = 0 ; i != Count; ++i) {
1198
+ if (key.getElement (i) != getElements ()[i])
1199
+ return false ;
1200
+ }
1201
+ return true ;
1202
+ }
1203
+
1204
+ friend llvm::hash_code hash_value (const MetadataPackCacheEntry &value) {
1205
+ return hash_value (value.getElements ());
1206
+ }
1207
+
1208
+ static size_t getExtraAllocationSize (const Key &key) {
1209
+ return getExtraAllocationSize (key.Count );
1210
+ }
1211
+
1212
+ size_t getExtraAllocationSize () const {
1213
+ return getExtraAllocationSize (Count);
1214
+ }
1215
+
1216
+ static size_t getExtraAllocationSize (unsigned count) {
1217
+ return count * sizeof (const Metadata * const *);
1218
+ }
1219
+ };
1220
+
1221
+ MetadataPackCacheEntry::MetadataPackCacheEntry (const Key &key) {
1222
+ auto count = key.getCount ();
1223
+
1224
+ for (unsigned i = 0 ; i < count; ++i)
1225
+ getElements ()[i] = key.getElement (i);
1226
+ }
1227
+
1228
+ } // end anonymous namespace
1229
+
1230
+ // / The uniquing structure for metadata packs.
1231
+ static SimpleGlobalCache<MetadataPackCacheEntry, MetadataPackTag> MetadataPacks;
1232
+
1233
+ SWIFT_RUNTIME_EXPORT SWIFT_CC (swift)
1234
+ const Metadata * const *
1235
+ swift_allocateMetadataPack(const Metadata * const *pack, unsigned count) {
1236
+ if (reinterpret_cast <uintptr_t >(pack) & 1 )
1237
+ return pack;
1238
+
1239
+ MetadataPackCacheEntry::Key key{pack, count};
1240
+ auto bytes = MetadataPacks.getOrInsert (key).first ->getElements ();
1241
+
1242
+ uintptr_t bytesWithLSBSet = reinterpret_cast <uintptr_t >(bytes) | 1 ;
1243
+ return reinterpret_cast <const Metadata * const *>(bytesWithLSBSet);
1244
+ }
1245
+
1246
+ SWIFT_RUNTIME_EXPORT SWIFT_CC (swift)
1247
+ const WitnessTable * const *
1248
+ swift_allocateWitnessTablePack(const WitnessTable * const *pack, unsigned count) {
1249
+ if (reinterpret_cast <uintptr_t >(pack) & 1 )
1250
+ return pack;
1251
+
1252
+ size_t totalSize = (size_t ) count * sizeof (const WitnessTable *);
1253
+
1254
+ auto bytes = (char *) MetadataAllocator (WitnessTablePackTag)
1255
+ .Allocate (totalSize, alignof (const WitnessTable *));
1256
+ memcpy (bytes, pack, totalSize);
1257
+
1258
+ uintptr_t bytesWithLSBSet = reinterpret_cast <uintptr_t >(bytes) | 1 ;
1259
+ return reinterpret_cast <const WitnessTable * const *>(bytesWithLSBSet);
1260
+ }
1261
+
1149
1262
/* **************************************************************************/
1150
1263
/* ** Functions *************************************************************/
1151
1264
/* **************************************************************************/
0 commit comments