Skip to content

Commit 4d37e2b

Browse files
authored
Merge pull request #16996 from mikeash/faster-infoForMetadata
[RemoteMirrors] Put a cache in front of getFieldTypeInfo to avoid repetitive scanning of the target's reflection infos.
2 parents 81658f4 + e6a9198 commit 4d37e2b

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ class TypeRefBuilder {
178178
std::unordered_map<TypeRefID, const TypeRef *,
179179
TypeRefID::Hash, TypeRefID::Equal> AssociatedTypeCache;
180180

181+
/// Cache for field info lookups.
182+
std::unordered_map<std::string,
183+
std::pair<const FieldDescriptor *, const ReflectionInfo *>>
184+
FieldTypeInfoCache;
185+
181186
TypeConverter TC;
182187
MetadataSourceBuilder MSB;
183188

stdlib/public/Reflection/TypeRefBuilder.cpp

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,25 @@ TypeRefBuilder::getRemoteAddrOfTypeRefPointer(const void *pointer) {
5050

5151
TypeRefBuilder::TypeRefBuilder() : TC(*this) {}
5252

53-
/// Determine whether the given reflection protocol name matches.
54-
static bool reflectionNameMatches(Demangler &dem,
55-
StringRef reflectionName,
56-
StringRef searchName) {
53+
/// Normalize a mangled name so it can be matched with string equality.
54+
static std::string normalizeReflectionName(Demangler &dem, StringRef reflectionName) {
5755
reflectionName = dropSwiftManglingPrefix(reflectionName);
5856

5957
// Remangle the reflection name to resolve symbolic references.
6058
if (auto node = dem.demangleType(reflectionName)) {
61-
auto remangled = mangleNode(node);
62-
return remangled == searchName;
59+
return mangleNode(node);
6360
}
64-
65-
// Fall back to string matching.
66-
return reflectionName.equals(searchName);
61+
62+
// Fall back to the raw string.
63+
return reflectionName;
64+
}
65+
66+
/// Determine whether the given reflection protocol name matches.
67+
static bool reflectionNameMatches(Demangler &dem,
68+
StringRef reflectionName,
69+
StringRef searchName) {
70+
auto normalized = normalizeReflectionName(dem, reflectionName);
71+
return searchName.equals(normalized);
6772
}
6873

6974
const TypeRef * TypeRefBuilder::
@@ -139,6 +144,12 @@ TypeRefBuilder::getFieldTypeInfo(const TypeRef *TR) {
139144
else
140145
return {};
141146

147+
// Try the cache.
148+
auto Found = FieldTypeInfoCache.find(MangledName);
149+
if (Found != FieldTypeInfoCache.end())
150+
return Found->second;
151+
152+
// On failure, fill out the cache with everything we know about.
142153
std::vector<std::pair<std::string, const TypeRef *>> Fields;
143154
for (auto &Info : ReflectionInfos) {
144155
uintptr_t TypeRefOffset = Info.Field.SectionOffset
@@ -147,12 +158,16 @@ TypeRefBuilder::getFieldTypeInfo(const TypeRef *TR) {
147158
if (!FD.hasMangledTypeName())
148159
continue;
149160
auto CandidateMangledName = FD.getMangledTypeName(TypeRefOffset);
150-
if (!reflectionNameMatches(Dem, CandidateMangledName, MangledName))
151-
continue;
152-
return {&FD, &Info};
161+
auto NormalizedName = normalizeReflectionName(Dem, CandidateMangledName);
162+
FieldTypeInfoCache[NormalizedName] = {&FD, &Info};
153163
}
154164
}
155165

166+
// We've filled the cache with everything we know about now. Try the cache again.
167+
Found = FieldTypeInfoCache.find(MangledName);
168+
if (Found != FieldTypeInfoCache.end())
169+
return Found->second;
170+
156171
return {nullptr, 0};
157172
}
158173

0 commit comments

Comments
 (0)