Skip to content

Commit e7ef0d3

Browse files
committed
Runtime: Also unique witness table packs
While we can't assume that pointer equality implies semantic equality with witness table packs, it still makes sense to unique their storage opportunistically.
1 parent 5a52fdb commit e7ef0d3

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,27 +1180,28 @@ swift::swift_getObjCClassFromMetadataConditional(const Metadata *theMetadata) {
11801180

11811181
namespace {
11821182

1183-
class MetadataPackCacheEntry {
1183+
template<typename PackType>
1184+
class PackCacheEntry {
11841185
public:
11851186
size_t Count;
11861187

1187-
const Metadata * const * getElements() const {
1188-
return reinterpret_cast<const Metadata * const *>(this + 1);
1188+
const PackType * const * getElements() const {
1189+
return reinterpret_cast<const PackType * const *>(this + 1);
11891190
}
11901191

1191-
const Metadata ** getElements() {
1192-
return reinterpret_cast<const Metadata **>(this + 1);
1192+
const PackType ** getElements() {
1193+
return reinterpret_cast<const PackType **>(this + 1);
11931194
}
11941195

11951196
struct Key {
1196-
const Metadata *const *Data;
1197+
const PackType *const *Data;
11971198
const size_t Count;
11981199

11991200
size_t getCount() const {
12001201
return Count;
12011202
}
12021203

1203-
const Metadata *getElement(size_t index) const {
1204+
const PackType *getElement(size_t index) const {
12041205
assert(index < Count);
12051206
return Data[index];
12061207
}
@@ -1213,7 +1214,7 @@ class MetadataPackCacheEntry {
12131214
}
12141215
};
12151216

1216-
MetadataPackCacheEntry(const Key &key);
1217+
PackCacheEntry(const Key &key);
12171218

12181219
intptr_t getKeyIntValueForDump() {
12191220
return 0; // No single meaningful value here.
@@ -1229,7 +1230,7 @@ class MetadataPackCacheEntry {
12291230
return true;
12301231
}
12311232

1232-
friend llvm::hash_code hash_value(const MetadataPackCacheEntry &value) {
1233+
friend llvm::hash_code hash_value(const PackCacheEntry<PackType> &value) {
12331234
llvm::hash_code hash = 0;
12341235
for (size_t i = 0; i != value.Count; ++i)
12351236
hash = llvm::hash_combine(hash, value.getElements()[i]);
@@ -1249,7 +1250,9 @@ class MetadataPackCacheEntry {
12491250
}
12501251
};
12511252

1252-
MetadataPackCacheEntry::MetadataPackCacheEntry(const Key &key) {
1253+
template<typename PackType>
1254+
PackCacheEntry<PackType>::PackCacheEntry(
1255+
const typename PackCacheEntry<PackType>::Key &key) {
12531256
Count = key.getCount();
12541257

12551258
for (unsigned i = 0; i < Count; ++i)
@@ -1259,7 +1262,8 @@ MetadataPackCacheEntry::MetadataPackCacheEntry(const Key &key) {
12591262
} // end anonymous namespace
12601263

12611264
/// The uniquing structure for metadata packs.
1262-
static SimpleGlobalCache<MetadataPackCacheEntry, MetadataPackTag> MetadataPacks;
1265+
static SimpleGlobalCache<PackCacheEntry<Metadata>,
1266+
MetadataPackTag> MetadataPacks;
12631267

12641268
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
12651269
const Metadata * const *
@@ -1268,25 +1272,25 @@ swift_allocateMetadataPack(const Metadata * const *ptr, size_t count) {
12681272
== PackLifetime::OnHeap)
12691273
return ptr;
12701274

1271-
MetadataPackCacheEntry::Key key{ptr, count};
1275+
PackCacheEntry<Metadata>::Key key{ptr, count};
12721276
auto bytes = MetadataPacks.getOrInsert(key).first->getElements();
12731277

12741278
return MetadataPackPointer(bytes, PackLifetime::OnHeap).getPointer();
12751279
}
12761280

1281+
/// The uniquing structure for witness table packs.
1282+
static SimpleGlobalCache<PackCacheEntry<WitnessTable>,
1283+
WitnessTablePackTag> WitnessTablePacks;
1284+
12771285
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
12781286
const WitnessTable * const *
12791287
swift_allocateWitnessTablePack(const WitnessTable * const *ptr, size_t count) {
12801288
if (WitnessTablePackPointer(reinterpret_cast<uintptr_t>(ptr)).getLifetime()
12811289
== PackLifetime::OnHeap)
12821290
return ptr;
12831291

1284-
size_t totalSize = (size_t) count * sizeof(const WitnessTable *);
1285-
1286-
auto bytes = (const WitnessTable **)
1287-
MetadataAllocator(WitnessTablePackTag)
1288-
.Allocate(totalSize, alignof(const WitnessTable *));
1289-
memcpy((char*) bytes, ptr, totalSize);
1292+
PackCacheEntry<WitnessTable>::Key key{ptr, count};
1293+
auto bytes = WitnessTablePacks.getOrInsert(key).first->getElements();
12901294

12911295
return WitnessTablePackPointer(bytes, PackLifetime::OnHeap).getPointer();
12921296
}

0 commit comments

Comments
 (0)