Skip to content

Commit 5cc28c9

Browse files
committed
Cache additional TypeRefBuilder operations
Speed up Remote Mirror significantly by caching two additional calculations in TypeRefBuilder. Resolves rdar://111248508
1 parent 5422f9a commit 5cc28c9

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,15 @@ class TypeRefBuilder {
424424
/// Cache for field info lookups.
425425
std::unordered_map<std::string, RemoteRef<FieldDescriptor>> FieldTypeInfoCache;
426426

427+
/// Cache for normalized reflection name lookups.
428+
std::unordered_map<uint64_t /* remote address */, llvm::Optional<std::string>>
429+
NormalizedReflectionNameCache;
430+
431+
/// Cache for built-in type descriptor lookups.
432+
std::unordered_map<std::string /* normalized name */,
433+
RemoteRef<BuiltinTypeDescriptor>>
434+
BuiltInTypeDescriptorCache;
435+
427436
std::vector<std::unique_ptr<const GenericSignatureRef>> SignatureRefPool;
428437

429438
TypeConverter TC;
@@ -1043,6 +1052,30 @@ class TypeRefBuilder {
10431052
ReflectionInfos.push_back(I);
10441053
auto InfoID = ReflectionInfos.size() - 1;
10451054
assert(InfoID <= UINT32_MAX && "ReflectionInfo ID overflow");
1055+
1056+
for (auto BuiltinTypeDescriptor : I.Builtin) {
1057+
if (BuiltinTypeDescriptor->Stride <= 0)
1058+
continue;
1059+
if (!BuiltinTypeDescriptor->hasMangledTypeName())
1060+
continue;
1061+
1062+
auto Alignment = BuiltinTypeDescriptor->getAlignment();
1063+
if (Alignment <= 0)
1064+
continue;
1065+
// Reject any alignment that's not a power of two.
1066+
if (Alignment & (Alignment - 1))
1067+
continue;
1068+
1069+
const auto CandidateMangledName =
1070+
readTypeRef(BuiltinTypeDescriptor, BuiltinTypeDescriptor->TypeName);
1071+
const auto CandidateNormalizedName =
1072+
normalizeReflectionName(CandidateMangledName);
1073+
if (CandidateNormalizedName) {
1074+
BuiltInTypeDescriptorCache.insert(
1075+
std::make_pair(*CandidateNormalizedName, BuiltinTypeDescriptor));
1076+
}
1077+
}
1078+
10461079
return InfoID;
10471080
}
10481081

stdlib/public/RemoteInspection/TypeRefBuilder.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ RemoteRef<char> TypeRefBuilder::readTypeRef(uint64_t remoteAddr) {
9393
/// Load and normalize a mangled name so it can be matched with string equality.
9494
llvm::Optional<std::string>
9595
TypeRefBuilder::normalizeReflectionName(RemoteRef<char> reflectionName) {
96+
const auto reflectionNameRemoteAddress = reflectionName.getAddressData();
97+
98+
if (const auto found =
99+
NormalizedReflectionNameCache.find(reflectionNameRemoteAddress);
100+
found != NormalizedReflectionNameCache.end()) {
101+
return found->second;
102+
}
103+
96104
ScopedNodeFactoryCheckpoint checkpoint(this);
97105
// Remangle the reflection name to resolve symbolic references.
98106
if (auto node = demangleTypeRef(reflectionName,
@@ -102,18 +110,27 @@ TypeRefBuilder::normalizeReflectionName(RemoteRef<char> reflectionName) {
102110
case Node::Kind::ProtocolSymbolicReference:
103111
case Node::Kind::OpaqueTypeDescriptorSymbolicReference:
104112
// Symbolic references cannot be mangled, return a failure.
113+
NormalizedReflectionNameCache.insert(std::make_pair(
114+
reflectionNameRemoteAddress, (llvm::Optional<std::string>){}));
105115
return {};
106116
default:
107117
auto mangling = mangleNode(node);
108118
if (!mangling.isSuccess()) {
119+
NormalizedReflectionNameCache.insert(std::make_pair(
120+
reflectionNameRemoteAddress, (llvm::Optional<std::string>){}));
109121
return {};
110122
}
123+
NormalizedReflectionNameCache.insert(
124+
std::make_pair(reflectionNameRemoteAddress, mangling.result()));
111125
return std::move(mangling.result());
112126
}
113127
}
114128

115129
// Fall back to the raw string.
116-
return getTypeRefString(reflectionName).str();
130+
const auto manglingResult = getTypeRefString(reflectionName).str();
131+
NormalizedReflectionNameCache.insert(
132+
std::make_pair(reflectionNameRemoteAddress, manglingResult));
133+
return std::move(manglingResult);
117134
}
118135

119136
/// Determine whether the given reflection protocol name matches.
@@ -398,26 +415,9 @@ TypeRefBuilder::getBuiltinTypeInfo(const TypeRef *TR) {
398415
else
399416
return nullptr;
400417

401-
for (auto Info : ReflectionInfos) {
402-
for (auto BuiltinTypeDescriptor : Info.Builtin) {
403-
if (BuiltinTypeDescriptor->Stride <= 0)
404-
continue;
405-
if (!BuiltinTypeDescriptor->hasMangledTypeName())
406-
continue;
407-
408-
auto Alignment = BuiltinTypeDescriptor->getAlignment();
409-
if (Alignment <= 0)
410-
continue;
411-
// Reject any alignment that's not a power of two.
412-
if (Alignment & (Alignment - 1))
413-
continue;
414-
415-
auto CandidateMangledName =
416-
readTypeRef(BuiltinTypeDescriptor, BuiltinTypeDescriptor->TypeName);
417-
if (!reflectionNameMatches(CandidateMangledName, MangledName))
418-
continue;
419-
return BuiltinTypeDescriptor;
420-
}
418+
if (const auto found = BuiltInTypeDescriptorCache.find(MangledName);
419+
found != BuiltInTypeDescriptorCache.end()) {
420+
return found->second;
421421
}
422422

423423
return nullptr;

0 commit comments

Comments
 (0)