@@ -207,7 +207,8 @@ struct TypeMetadataPrivateState {
207
207
llvm::DenseMap<llvm::StringRef,
208
208
llvm::TinyPtrVector<const ContextDescriptor *>>
209
209
ContextDescriptorCache;
210
- size_t ContextDescriptorLastSectionScanned = 0 ;
210
+ size_t ConformanceDescriptorLastSectionScanned = 0 ;
211
+ size_t TypeContextDescriptorLastSectionScanned = 0 ;
211
212
Mutex ContextDescriptorCacheLock;
212
213
213
214
TypeMetadataPrivateState () {
@@ -225,6 +226,28 @@ _registerTypeMetadataRecords(TypeMetadataPrivateState &T,
225
226
T.SectionsToScan .push_back (TypeMetadataSection{begin, end});
226
227
}
227
228
229
+ // / Iterate over type metadata sections starting from the given index.
230
+ // / The index is updated to the current number of sections. Passing
231
+ // / the same index to the next call will iterate over any sections that were
232
+ // / added after the previous call.
233
+ // /
234
+ // / Takes a function to call for each section found. The two parameters are
235
+ // / the start and end of the section.
236
+ static void _forEachTypeMetadataSectionAfter (
237
+ TypeMetadataPrivateState &T,
238
+ size_t *start,
239
+ const std::function<void (const TypeMetadataRecord *,
240
+ const TypeMetadataRecord *)> &f) {
241
+ auto snapshot = T.SectionsToScan .snapshot ();
242
+ if (snapshot.Count > *start) {
243
+ auto *begin = snapshot.begin () + *start;
244
+ auto *end = snapshot.end ();
245
+ for (auto *section = begin; section != end; section++) {
246
+ f (section->Begin , section->End );
247
+ }
248
+ }
249
+ }
250
+
228
251
void swift::addImageTypeMetadataRecordBlockCallback (const void *records,
229
252
uintptr_t recordsSize) {
230
253
assert (recordsSize % sizeof (TypeMetadataRecord) == 0
@@ -618,8 +641,24 @@ _searchTypeMetadataRecords(TypeMetadataPrivateState &T,
618
641
// scanned, if any.
619
642
static void
620
643
_scanAdditionalContextDescriptors (TypeMetadataPrivateState &T) {
644
+ _forEachTypeMetadataSectionAfter (
645
+ T,
646
+ &T.TypeContextDescriptorLastSectionScanned ,
647
+ [&T](const TypeMetadataRecord *Begin,
648
+ const TypeMetadataRecord *End) {
649
+ for (const auto *record = Begin; record != End; record++) {
650
+ if (auto ntd = record->getContextDescriptor ()) {
651
+ if (auto type = llvm::dyn_cast<TypeContextDescriptor>(ntd)) {
652
+ auto identity = ParsedTypeIdentity::parse (type);
653
+ auto name = identity.getABIName ();
654
+ T.ContextDescriptorCache [name].push_back (type);
655
+ }
656
+ }
657
+ }
658
+ });
659
+
621
660
_forEachProtocolConformanceSectionAfter (
622
- &T.ContextDescriptorLastSectionScanned ,
661
+ &T.ConformanceDescriptorLastSectionScanned ,
623
662
[&T](const ProtocolConformanceRecord *Begin,
624
663
const ProtocolConformanceRecord *End) {
625
664
for (const auto *record = Begin; record != End; record++) {
0 commit comments