@@ -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