Skip to content

Commit 6b23b07

Browse files
committed
[RemoteMirror] Optmiize brute-force search in readTypeRef()
1 parent 135ce46 commit 6b23b07

File tree

2 files changed

+76
-5
lines changed

2 files changed

+76
-5
lines changed

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,14 @@ class TypeRefBuilder {
529529
bool reflectionNameMatches(RemoteRef<char> reflectionName,
530530
StringRef searchName);
531531

532+
std::optional<std::reference_wrapper<const ReflectionInfo>>
533+
findReflectionInfoWithTypeRefContainingAddress(uint64_t remoteAddr);
534+
532535
std::vector<ReflectionInfo> ReflectionInfos;
533536

537+
// Sorted indexes of elements in ReflectionInfos.
538+
std::vector<uint32_t> ReflectionInfoIndexesSortedByTypeReferenceRange;
539+
534540
/// Indexes of Reflection Infos we've already processed.
535541
llvm::DenseSet<size_t> ProcessedReflectionInfoIndexes;
536542

stdlib/public/RemoteInspection/TypeRefBuilder.cpp

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,83 @@ TypeRefBuilder::decodeMangledType(Node *node, bool forRequirement) {
3737
.getType();
3838
}
3939

40+
std::optional<std::reference_wrapper<const ReflectionInfo>>
41+
TypeRefBuilder::ReflectionTypeDescriptorFinder::
42+
findReflectionInfoWithTypeRefContainingAddress(uint64_t remoteAddr) {
43+
// Update ReflectionInfoIndexesSortedByTypeReferenceRange if necessary.
44+
if (ReflectionInfoIndexesSortedByTypeReferenceRange.size() !=
45+
ReflectionInfos.size()) {
46+
for (size_t reflectionInfoIndex =
47+
ReflectionInfoIndexesSortedByTypeReferenceRange.size();
48+
reflectionInfoIndex < ReflectionInfos.size(); reflectionInfoIndex++) {
49+
ReflectionInfoIndexesSortedByTypeReferenceRange.push_back(
50+
(uint32_t)reflectionInfoIndex);
51+
}
52+
53+
std::sort(
54+
ReflectionInfoIndexesSortedByTypeReferenceRange.begin(),
55+
ReflectionInfoIndexesSortedByTypeReferenceRange.end(),
56+
[&](uint32_t ReflectionInfoIndexA, uint32_t ReflectionInfoIndexB) {
57+
uint64_t typeReferenceAStart = ReflectionInfos[ReflectionInfoIndexA]
58+
.TypeReference.startAddress()
59+
.getAddressData();
60+
uint64_t typeReferenceBStart = ReflectionInfos[ReflectionInfoIndexB]
61+
.TypeReference.startAddress()
62+
.getAddressData();
63+
64+
return typeReferenceAStart < typeReferenceBStart;
65+
});
66+
}
67+
68+
// Use std::lower_bound() to search
69+
// ReflectionInfoIndexesSortedByTypeReferenceRange for a ReflectionInfo whose
70+
// TypeReference contains remoteAddr.
71+
const auto possiblyMatchingReflectionInfoIndex = std::lower_bound(
72+
ReflectionInfoIndexesSortedByTypeReferenceRange.begin(),
73+
ReflectionInfoIndexesSortedByTypeReferenceRange.end(), remoteAddr,
74+
[&](uint32_t ReflectionInfoIndex, uint64_t remoteAddr) {
75+
return ReflectionInfos[ReflectionInfoIndex]
76+
.TypeReference.endAddress()
77+
.getAddressData() <= remoteAddr;
78+
});
79+
80+
if (possiblyMatchingReflectionInfoIndex ==
81+
ReflectionInfoIndexesSortedByTypeReferenceRange.end()) {
82+
// There is no ReflectionInfo whose TypeReference ends before remoteAddr.
83+
return std::nullopt;
84+
}
85+
86+
const ReflectionInfo &possiblyMatchingReflectionInfo =
87+
ReflectionInfos[*possiblyMatchingReflectionInfoIndex];
88+
if (!possiblyMatchingReflectionInfo.TypeReference.containsRemoteAddress(
89+
remoteAddr, 1)) {
90+
// possiblyMatchingTypeReference ends before remoteAddr, but it doesn't
91+
// contain remoteAddr.
92+
return std::nullopt;
93+
}
94+
95+
// possiblyMatchingTypeReference contains remoteAddr.
96+
return possiblyMatchingReflectionInfo;
97+
}
98+
4099
RemoteRef<char> TypeRefBuilder::ReflectionTypeDescriptorFinder::readTypeRef(
41100
uint64_t remoteAddr) {
42101
// The remote address should point into one of the TypeRef or
43102
// ReflectionString references we already read out of the images.
44103
RemoteRef<char> foundTypeRef;
45104
RemoteRef<void> limitAddress;
105+
106+
const auto infoWithTypeReferenceContainingAddress =
107+
findReflectionInfoWithTypeRefContainingAddress(remoteAddr);
108+
if (infoWithTypeReferenceContainingAddress.has_value()) {
109+
foundTypeRef = infoWithTypeReferenceContainingAddress->get()
110+
.TypeReference.getRemoteRef<char>(remoteAddr);
111+
limitAddress = infoWithTypeReferenceContainingAddress->get()
112+
.TypeReference.endAddress();
113+
goto found_type_ref;
114+
}
115+
46116
for (auto &info : ReflectionInfos) {
47-
if (info.TypeReference.containsRemoteAddress(remoteAddr, 1)) {
48-
foundTypeRef = info.TypeReference.getRemoteRef<char>(remoteAddr);
49-
limitAddress = info.TypeReference.endAddress();
50-
goto found_type_ref;
51-
}
52117
if (info.ReflectionString.containsRemoteAddress(remoteAddr, 1)) {
53118
foundTypeRef = info.ReflectionString.getRemoteRef<char>(remoteAddr);
54119
limitAddress = info.ReflectionString.endAddress();

0 commit comments

Comments
 (0)