22
22
#include " swift/Runtime/HeapObject.h"
23
23
#include " swift/Runtime/Metadata.h"
24
24
#include " swift/Basic/Unreachable.h"
25
+ #include " llvm/ADT/DenseMap.h"
25
26
#include " CompatibilityOverride.h"
26
27
#include " ImageInspection.h"
27
28
#include " Private.h"
@@ -470,6 +471,7 @@ swift_conformsToProtocolImpl(const Metadata *const type,
470
471
return found.second ;
471
472
472
473
// Scan conformance records.
474
+ llvm::SmallDenseMap<const Metadata *, const WitnessTable *> foundWitnesses;
473
475
auto processSection = [&](const ConformanceSection §ion) {
474
476
// Eagerly pull records for nondependent witnesses into our cache.
475
477
auto processDescriptor = [&](const ProtocolConformanceDescriptor &descriptor) {
@@ -484,6 +486,7 @@ swift_conformsToProtocolImpl(const Metadata *const type,
484
486
if (auto *matchingType = candidate.getMatchingType (type)) {
485
487
auto witness = descriptor.getWitnessTable (matchingType);
486
488
C.cacheResult (matchingType, protocol, witness, /* always cache*/ 0 );
489
+ foundWitnesses.insert ({matchingType, witness});
487
490
}
488
491
};
489
492
@@ -505,14 +508,23 @@ swift_conformsToProtocolImpl(const Metadata *const type,
505
508
processSection (section);
506
509
}
507
510
508
- // Try the search again to look for the most specific cached conformance.
509
- found = searchInConformanceCache (type, protocol);
511
+ // Find the most specific conformance that was scanned.
512
+ const WitnessTable *foundWitness = nullptr ;
513
+ const Metadata *searchType = type;
514
+ while (!foundWitness && searchType) {
515
+ foundWitness = foundWitnesses.lookup (searchType);
510
516
511
- // If it's not authoritative, then add an authoritative entry for this type.
512
- if (!found.first )
513
- C.cacheResult (type, protocol, found.second , snapshot.count ());
517
+ // If there's no entry here, move up to the superclass (if any).
518
+ if (!foundWitness)
519
+ searchType = _swift_class_getSuperclass (searchType);
520
+ }
521
+
522
+ // If it's for a superclass or if we didn't find anything, then add an
523
+ // authoritative entry for this type.
524
+ if (searchType != type)
525
+ C.cacheResult (type, protocol, foundWitness, snapshot.count ());
514
526
515
- return found. second ;
527
+ return foundWitness ;
516
528
}
517
529
518
530
const ContextDescriptor *
0 commit comments