Skip to content

Commit 9eebee8

Browse files
authored
Merge pull request #80844 from DougGregor/conformance-cache-entry-stole-the-wrong-bit
[Runtime] Don't use the low bit of a WitnessTable pointer in the conformance cache
2 parents d72763f + 5f00437 commit 9eebee8

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -537,47 +537,80 @@ namespace {
537537

538538
struct ConformanceCacheEntry {
539539
private:
540-
ConformanceCacheKey Key;
540+
/// Storage used when we have global actor isolation on the conformance.
541+
struct ExtendedStorage {
542+
/// The protocol to which the type conforms.
543+
const ProtocolDescriptor *Proto;
544+
545+
/// The global actor to which this conformance is isolated, or NULL for
546+
/// a nonisolated conformances.
547+
const Metadata *globalActorIsolationType = nullptr;
548+
549+
/// When the conformance is global-actor-isolated, this is the conformance
550+
/// of globalActorIsolationType to GlobalActor.
551+
const WitnessTable *globalActorIsolationWitnessTable = nullptr;
552+
};
553+
554+
const Metadata *Type;
555+
llvm::PointerUnion<const ProtocolDescriptor *, const ExtendedStorage *>
556+
ProtoOrStorage;
541557

542-
/// The witness table or along with a bit that indicates whether the
543-
/// conformance is isolated to a global actor.
544-
llvm::PointerUnion<const WitnessTable *, const ConformanceLookupResult *>
545-
WitnessTableOrLookupResult;
558+
/// The witness table.
559+
const WitnessTable *Witness;
546560

547561
public:
548562
ConformanceCacheEntry(ConformanceCacheKey key,
549563
ConformanceLookupResult result)
550-
: Key(key) {
564+
: Type(key.Type), Witness(result.witnessTable)
565+
{
551566
if (result.globalActorIsolationType) {
552-
WitnessTableOrLookupResult = new ConformanceLookupResult(result);
567+
ProtoOrStorage = new ExtendedStorage{
568+
key.Proto, result.globalActorIsolationType,
569+
result.globalActorIsolationWitnessTable
570+
};
553571
} else {
554-
WitnessTableOrLookupResult = result.witnessTable;
572+
ProtoOrStorage = key.Proto;
555573
}
556574
}
557575

558576
bool matchesKey(const ConformanceCacheKey &key) const {
559-
return Key.Type == key.Type && Key.Proto == key.Proto;
577+
return Type == key.Type && getProtocol() == key.Proto;
560578
}
561579

562580
friend llvm::hash_code hash_value(const ConformanceCacheEntry &entry) {
563-
return hash_value(entry.Key);
581+
return hash_value(entry.getKey());
582+
}
583+
584+
/// Get the protocol.
585+
const ProtocolDescriptor *getProtocol() const {
586+
if (auto proto = ProtoOrStorage.dyn_cast<const ProtocolDescriptor *>())
587+
return proto;
588+
589+
if (auto storage = ProtoOrStorage.dyn_cast<const ExtendedStorage *>())
590+
return storage->Proto;
591+
592+
return nullptr;
593+
}
594+
595+
/// Get the conformance cache key.
596+
ConformanceCacheKey getKey() const {
597+
return ConformanceCacheKey(Type, getProtocol());
564598
}
565599

566600
/// Get the cached witness table, or null if we cached failure.
567601
const WitnessTable *getWitnessTable() const {
568-
if (auto witnessTable = WitnessTableOrLookupResult.dyn_cast<const WitnessTable *>())
569-
return witnessTable;
570-
571-
return WitnessTableOrLookupResult.get<const ConformanceLookupResult *>()
572-
->witnessTable;
602+
return Witness;
573603
}
574604

575605
ConformanceLookupResult getResult() const {
576-
if (auto witnessTable = WitnessTableOrLookupResult.dyn_cast<const WitnessTable *>())
577-
return ConformanceLookupResult { witnessTable, nullptr, nullptr };
606+
if (ProtoOrStorage.is<const ProtocolDescriptor *>())
607+
return ConformanceLookupResult { Witness, nullptr, nullptr };
578608

579-
if (auto lookupResult = WitnessTableOrLookupResult.dyn_cast<const ConformanceLookupResult *>())
580-
return *lookupResult;
609+
if (auto storage = ProtoOrStorage.dyn_cast<const ExtendedStorage *>()) {
610+
return ConformanceLookupResult(
611+
Witness, storage->globalActorIsolationType,
612+
storage->globalActorIsolationWitnessTable);
613+
}
581614

582615
return nullptr;
583616
}

0 commit comments

Comments
 (0)