@@ -537,47 +537,77 @@ 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+ return ProtoOrStorage.get <const ExtendedStorage *>()->Proto ;
590+ }
591+
592+ // / Get the conformance cache key.
593+ ConformanceCacheKey getKey () const {
594+ return ConformanceCacheKey (Type, getProtocol ());
564595 }
565596
566597 // / Get the cached witness table, or null if we cached failure.
567598 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 ;
599+ return Witness;
573600 }
574601
575602 ConformanceLookupResult getResult () const {
576- if (auto witnessTable = WitnessTableOrLookupResult. dyn_cast <const WitnessTable *>())
577- return ConformanceLookupResult { witnessTable , nullptr , nullptr };
603+ if (ProtoOrStorage. is <const ProtocolDescriptor *>())
604+ return ConformanceLookupResult { Witness , nullptr , nullptr };
578605
579- if (auto lookupResult = WitnessTableOrLookupResult.dyn_cast <const ConformanceLookupResult *>())
580- return *lookupResult;
606+ if (auto storage = ProtoOrStorage.dyn_cast <const ExtendedStorage *>()) {
607+ return ConformanceLookupResult (
608+ Witness, storage->globalActorIsolationType ,
609+ storage->globalActorIsolationWitnessTable );
610+ }
581611
582612 return nullptr ;
583613 }
0 commit comments