Skip to content

Commit a6a969c

Browse files
committed
Populate context descriptor cache from type metadata sections
1 parent ccfdb67 commit a6a969c

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ struct TypeMetadataPrivateState {
207207
llvm::DenseMap<llvm::StringRef,
208208
llvm::TinyPtrVector<const ContextDescriptor *>>
209209
ContextDescriptorCache;
210-
size_t ContextDescriptorLastSectionScanned = 0;
210+
size_t ConformanceDescriptorLastSectionScanned = 0;
211+
size_t TypeContextDescriptorLastSectionScanned = 0;
211212
Mutex ContextDescriptorCacheLock;
212213

213214
TypeMetadataPrivateState() {
@@ -225,6 +226,28 @@ _registerTypeMetadataRecords(TypeMetadataPrivateState &T,
225226
T.SectionsToScan.push_back(TypeMetadataSection{begin, end});
226227
}
227228

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+
228251
void swift::addImageTypeMetadataRecordBlockCallback(const void *records,
229252
uintptr_t recordsSize) {
230253
assert(recordsSize % sizeof(TypeMetadataRecord) == 0
@@ -618,8 +641,24 @@ _searchTypeMetadataRecords(TypeMetadataPrivateState &T,
618641
// scanned, if any.
619642
static void
620643
_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+
621660
_forEachProtocolConformanceSectionAfter(
622-
&T.ContextDescriptorLastSectionScanned,
661+
&T.ConformanceDescriptorLastSectionScanned,
623662
[&T](const ProtocolConformanceRecord *Begin,
624663
const ProtocolConformanceRecord *End) {
625664
for (const auto *record = Begin; record != End; record++) {

0 commit comments

Comments
 (0)