@@ -537,47 +537,80 @@ namespace {
537
537
538
538
struct ConformanceCacheEntry {
539
539
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;
541
557
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;
546
560
547
561
public:
548
562
ConformanceCacheEntry (ConformanceCacheKey key,
549
563
ConformanceLookupResult result)
550
- : Key(key) {
564
+ : Type(key.Type), Witness(result.witnessTable)
565
+ {
551
566
if (result.globalActorIsolationType ) {
552
- WitnessTableOrLookupResult = new ConformanceLookupResult (result);
567
+ ProtoOrStorage = new ExtendedStorage{
568
+ key.Proto , result.globalActorIsolationType ,
569
+ result.globalActorIsolationWitnessTable
570
+ };
553
571
} else {
554
- WitnessTableOrLookupResult = result. witnessTable ;
572
+ ProtoOrStorage = key. Proto ;
555
573
}
556
574
}
557
575
558
576
bool matchesKey (const ConformanceCacheKey &key) const {
559
- return Key. Type == key.Type && Key. Proto == key.Proto ;
577
+ return Type == key.Type && getProtocol () == key.Proto ;
560
578
}
561
579
562
580
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 ());
564
598
}
565
599
566
600
// / Get the cached witness table, or null if we cached failure.
567
601
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;
573
603
}
574
604
575
605
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 };
578
608
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
+ }
581
614
582
615
return nullptr ;
583
616
}
0 commit comments