@@ -326,14 +326,11 @@ void ConformanceState::verify() const {
326
326
// Iterate over all of the sections and verify all of the protocol
327
327
// descriptors.
328
328
auto &Self = const_cast <ConformanceState &>(*this );
329
- Self.SectionsToScan .read ([](const ConformanceSection *ptr, size_t count) -> char {
330
- for (size_t i = 0 ; i < count; i++) {
331
- for (const auto &Record : ptr[i]) {
332
- Record.get ()->verify ();
333
- }
329
+ for (const auto &Section : Self.SectionsToScan .snapshot ()) {
330
+ for (const auto &Record : Section) {
331
+ Record.get ()->verify ();
334
332
}
335
- return 0 ;
336
- });
333
+ }
337
334
}
338
335
#endif
339
336
@@ -445,7 +442,7 @@ searchInConformanceCache(const Metadata *type,
445
442
}
446
443
447
444
// Check if the negative cache entry is up-to-date.
448
- if (Value->getFailureGeneration () == C.SectionsToScan .count ()) {
445
+ if (Value->getFailureGeneration () == C.SectionsToScan .snapshot (). count ()) {
449
446
// Negative cache entry is up-to-date. Return failure along with
450
447
// the original query type's own cache entry, if we found one.
451
448
// (That entry may be out of date but the caller still has use for it.)
@@ -546,100 +543,94 @@ swift_conformsToProtocolImpl(const Metadata * const type,
546
543
auto failureEntry = FoundConformance.failureEntry ;
547
544
548
545
// Prepare to scan conformance records.
549
- size_t scannedCount;
550
- auto returnNull = C.SectionsToScan
551
- .read ([&](const ConformanceSection *ptr, size_t count) -> bool {
552
- scannedCount = count;
553
- // Scan only sections that were not scanned yet.
554
- // If we found an out-of-date negative cache entry,
555
- // we need not to re-scan the sections that it covers.
556
- auto startIndex = failureEntry ? failureEntry->getFailureGeneration () : 0 ;
557
- auto endIndex = count;
546
+ auto snapshot = C.SectionsToScan .snapshot ();
558
547
559
- // If there are no unscanned sections outstanding
560
- // then we can cache failure and give up now.
561
- if (startIndex == endIndex) {
562
- C.cacheFailure (type, protocol, count);
563
- return true ;
548
+ // Scan only sections that were not scanned yet.
549
+ // If we found an out-of-date negative cache entry,
550
+ // we need not to re-scan the sections that it covers.
551
+ auto startIndex = failureEntry ? failureEntry->getFailureGeneration () : 0 ;
552
+ auto endIndex = snapshot.count ();
553
+
554
+ // If there are no unscanned sections outstanding
555
+ // then we can cache failure and give up now.
556
+ if (startIndex == endIndex) {
557
+ C.cacheFailure (type, protocol, snapshot.count ());
558
+ return nullptr ;
559
+ }
560
+
561
+ // / Local function to retrieve the witness table and record the result.
562
+ auto recordWitnessTable = [&](const ProtocolConformanceDescriptor &descriptor,
563
+ const Metadata *type) {
564
+ switch (descriptor.getConformanceKind ()) {
565
+ case ConformanceFlags::ConformanceKind::WitnessTable:
566
+ // If the record provides a nondependent witness table for all
567
+ // instances of a generic type, cache it for the generic pattern.
568
+ C.cacheSuccess (type, protocol, descriptor.getStaticWitnessTable ());
569
+ return ;
570
+
571
+ case ConformanceFlags::ConformanceKind::WitnessTableAccessor:
572
+ // If the record provides a dependent witness table accessor,
573
+ // cache the result for the instantiated type metadata.
574
+ C.cacheSuccess (type, protocol, descriptor.getWitnessTable (type));
575
+ return ;
576
+
577
+ case ConformanceFlags::ConformanceKind::ConditionalWitnessTableAccessor: {
578
+ auto witnessTable = descriptor.getWitnessTable (type);
579
+ if (witnessTable)
580
+ C.cacheSuccess (type, protocol, witnessTable);
581
+ else
582
+ C.cacheFailure (type, protocol, snapshot.count ());
583
+ return ;
584
+ }
564
585
}
565
586
566
- // / Local function to retrieve the witness table and record the result.
567
- auto recordWitnessTable = [&](const ProtocolConformanceDescriptor &descriptor,
568
- const Metadata *type) {
569
- switch (descriptor.getConformanceKind ()) {
570
- case ConformanceFlags::ConformanceKind::WitnessTable:
571
- // If the record provides a nondependent witness table for all
572
- // instances of a generic type, cache it for the generic pattern.
573
- C.cacheSuccess (type, protocol, descriptor.getStaticWitnessTable ());
574
- return ;
575
-
576
- case ConformanceFlags::ConformanceKind::WitnessTableAccessor:
577
- // If the record provides a dependent witness table accessor,
578
- // cache the result for the instantiated type metadata.
579
- C.cacheSuccess (type, protocol, descriptor.getWitnessTable (type));
580
- return ;
581
-
582
- case ConformanceFlags::ConformanceKind::ConditionalWitnessTableAccessor: {
583
- auto witnessTable = descriptor.getWitnessTable (type);
584
- if (witnessTable)
585
- C.cacheSuccess (type, protocol, witnessTable);
586
- else
587
- C.cacheFailure (type, protocol, count);
588
- return ;
589
- }
590
- }
587
+ // Always fail, because we cannot interpret a future conformance
588
+ // kind.
589
+ C.cacheFailure (type, protocol, snapshot.count ());
590
+ };
591
591
592
- // Always fail, because we cannot interpret a future conformance
593
- // kind.
594
- C.cacheFailure (type, protocol, count);
595
- };
596
-
597
- // Really scan conformance records.
598
- for (size_t i = startIndex; i < endIndex; i++) {
599
- auto §ion = ptr[i];
600
- // Eagerly pull records for nondependent witnesses into our cache.
601
- for (const auto &record : section) {
602
- auto &descriptor = *record.get ();
603
-
604
- // If the record applies to a specific type, cache it.
605
- if (auto metadata = descriptor.getCanonicalTypeMetadata ()) {
606
- auto P = descriptor.getProtocol ();
607
-
608
- // Look for an exact match.
609
- if (protocol != P)
610
- continue ;
611
-
612
- if (!isRelatedType (type, metadata, /* candidateIsMetadata=*/ true ))
613
- continue ;
614
-
615
- // Record the witness table.
616
- recordWitnessTable (descriptor, metadata);
617
-
618
- // TODO: "Nondependent witness table" probably deserves its own flag.
619
- // An accessor function might still be necessary even if the witness table
620
- // can be shared.
621
- } else if (descriptor.getTypeKind ()
622
- == TypeMetadataRecordKind::DirectNominalTypeDescriptor ||
623
- descriptor.getTypeKind ()
624
- == TypeMetadataRecordKind::IndirectNominalTypeDescriptor) {
625
- auto R = descriptor.getTypeContextDescriptor ();
626
- auto P = descriptor.getProtocol ();
627
-
628
- // Look for an exact match.
629
- if (protocol != P)
630
- continue ;
631
-
632
- if (!isRelatedType (type, R, /* candidateIsMetadata=*/ false ))
633
- continue ;
634
-
635
- recordWitnessTable (descriptor, type);
636
- }
592
+ // Really scan conformance records.
593
+ for (size_t i = startIndex; i < endIndex; i++) {
594
+ auto §ion = snapshot.Start [i];
595
+ // Eagerly pull records for nondependent witnesses into our cache.
596
+ for (const auto &record : section) {
597
+ auto &descriptor = *record.get ();
598
+
599
+ // If the record applies to a specific type, cache it.
600
+ if (auto metadata = descriptor.getCanonicalTypeMetadata ()) {
601
+ auto P = descriptor.getProtocol ();
602
+
603
+ // Look for an exact match.
604
+ if (protocol != P)
605
+ continue ;
606
+
607
+ if (!isRelatedType (type, metadata, /* candidateIsMetadata=*/ true ))
608
+ continue ;
609
+
610
+ // Record the witness table.
611
+ recordWitnessTable (descriptor, metadata);
612
+
613
+ // TODO: "Nondependent witness table" probably deserves its own flag.
614
+ // An accessor function might still be necessary even if the witness table
615
+ // can be shared.
616
+ } else if (descriptor.getTypeKind ()
617
+ == TypeMetadataRecordKind::DirectNominalTypeDescriptor ||
618
+ descriptor.getTypeKind ()
619
+ == TypeMetadataRecordKind::IndirectNominalTypeDescriptor) {
620
+ auto R = descriptor.getTypeContextDescriptor ();
621
+ auto P = descriptor.getProtocol ();
622
+
623
+ // Look for an exact match.
624
+ if (protocol != P)
625
+ continue ;
626
+
627
+ if (!isRelatedType (type, R, /* candidateIsMetadata=*/ false ))
628
+ continue ;
629
+
630
+ recordWitnessTable (descriptor, type);
637
631
}
638
632
}
639
- return false ;
640
- });
641
-
642
- if (returnNull) return nullptr ;
633
+ }
643
634
644
635
// Conformance scan is complete.
645
636
// Search the cache once more, and this time update the cache if necessary.
@@ -648,7 +639,7 @@ swift_conformsToProtocolImpl(const Metadata * const type,
648
639
if (FoundConformance.isAuthoritative ) {
649
640
return FoundConformance.witnessTable ;
650
641
} else {
651
- C.cacheFailure (type, protocol, scannedCount );
642
+ C.cacheFailure (type, protocol, snapshot. count () );
652
643
return nullptr ;
653
644
}
654
645
}
@@ -657,19 +648,15 @@ const TypeContextDescriptor *
657
648
swift::_searchConformancesByMangledTypeName (Demangle::NodePointer node) {
658
649
auto &C = Conformances.get ();
659
650
660
- return C.SectionsToScan
661
- .read ([&](const ConformanceSection *ptr, size_t count) -> const TypeContextDescriptor * {
662
- for (size_t i = 0 ; i < count; i++) {
663
- auto §ion = ptr[i];
664
- for (const auto &record : section) {
665
- if (auto ntd = record->getTypeContextDescriptor ()) {
666
- if (_contextDescriptorMatchesMangling (ntd, node))
667
- return ntd;
668
- }
651
+ for (auto §ion : C.SectionsToScan .snapshot ()) {
652
+ for (const auto &record : section) {
653
+ if (auto ntd = record->getTypeContextDescriptor ()) {
654
+ if (_contextDescriptorMatchesMangling (ntd, node))
655
+ return ntd;
669
656
}
670
657
}
671
- return nullptr ;
672
- }) ;
658
+ }
659
+ return nullptr ;
673
660
}
674
661
675
662
// / Resolve a reference to a generic parameter to type metadata.
0 commit comments