mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[RemoteMirror] Optmiize brute-force search in readTypeRef()
This commit is contained in:
@@ -529,8 +529,14 @@ public:
|
|||||||
bool reflectionNameMatches(RemoteRef<char> reflectionName,
|
bool reflectionNameMatches(RemoteRef<char> reflectionName,
|
||||||
StringRef searchName);
|
StringRef searchName);
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<const ReflectionInfo>>
|
||||||
|
findReflectionInfoWithTypeRefContainingAddress(uint64_t remoteAddr);
|
||||||
|
|
||||||
std::vector<ReflectionInfo> ReflectionInfos;
|
std::vector<ReflectionInfo> ReflectionInfos;
|
||||||
|
|
||||||
|
// Sorted indexes of elements in ReflectionInfos.
|
||||||
|
std::vector<uint32_t> ReflectionInfoIndexesSortedByTypeReferenceRange;
|
||||||
|
|
||||||
/// Indexes of Reflection Infos we've already processed.
|
/// Indexes of Reflection Infos we've already processed.
|
||||||
llvm::DenseSet<size_t> ProcessedReflectionInfoIndexes;
|
llvm::DenseSet<size_t> ProcessedReflectionInfoIndexes;
|
||||||
|
|
||||||
|
|||||||
@@ -37,18 +37,83 @@ TypeRefBuilder::decodeMangledType(Node *node, bool forRequirement) {
|
|||||||
.getType();
|
.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<const ReflectionInfo>>
|
||||||
|
TypeRefBuilder::ReflectionTypeDescriptorFinder::
|
||||||
|
findReflectionInfoWithTypeRefContainingAddress(uint64_t remoteAddr) {
|
||||||
|
// Update ReflectionInfoIndexesSortedByTypeReferenceRange if necessary.
|
||||||
|
if (ReflectionInfoIndexesSortedByTypeReferenceRange.size() !=
|
||||||
|
ReflectionInfos.size()) {
|
||||||
|
for (size_t reflectionInfoIndex =
|
||||||
|
ReflectionInfoIndexesSortedByTypeReferenceRange.size();
|
||||||
|
reflectionInfoIndex < ReflectionInfos.size(); reflectionInfoIndex++) {
|
||||||
|
ReflectionInfoIndexesSortedByTypeReferenceRange.push_back(
|
||||||
|
(uint32_t)reflectionInfoIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(
|
||||||
|
ReflectionInfoIndexesSortedByTypeReferenceRange.begin(),
|
||||||
|
ReflectionInfoIndexesSortedByTypeReferenceRange.end(),
|
||||||
|
[&](uint32_t ReflectionInfoIndexA, uint32_t ReflectionInfoIndexB) {
|
||||||
|
uint64_t typeReferenceAStart = ReflectionInfos[ReflectionInfoIndexA]
|
||||||
|
.TypeReference.startAddress()
|
||||||
|
.getAddressData();
|
||||||
|
uint64_t typeReferenceBStart = ReflectionInfos[ReflectionInfoIndexB]
|
||||||
|
.TypeReference.startAddress()
|
||||||
|
.getAddressData();
|
||||||
|
|
||||||
|
return typeReferenceAStart < typeReferenceBStart;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use std::lower_bound() to search
|
||||||
|
// ReflectionInfoIndexesSortedByTypeReferenceRange for a ReflectionInfo whose
|
||||||
|
// TypeReference contains remoteAddr.
|
||||||
|
const auto possiblyMatchingReflectionInfoIndex = std::lower_bound(
|
||||||
|
ReflectionInfoIndexesSortedByTypeReferenceRange.begin(),
|
||||||
|
ReflectionInfoIndexesSortedByTypeReferenceRange.end(), remoteAddr,
|
||||||
|
[&](uint32_t ReflectionInfoIndex, uint64_t remoteAddr) {
|
||||||
|
return ReflectionInfos[ReflectionInfoIndex]
|
||||||
|
.TypeReference.endAddress()
|
||||||
|
.getAddressData() <= remoteAddr;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (possiblyMatchingReflectionInfoIndex ==
|
||||||
|
ReflectionInfoIndexesSortedByTypeReferenceRange.end()) {
|
||||||
|
// There is no ReflectionInfo whose TypeReference ends before remoteAddr.
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReflectionInfo &possiblyMatchingReflectionInfo =
|
||||||
|
ReflectionInfos[*possiblyMatchingReflectionInfoIndex];
|
||||||
|
if (!possiblyMatchingReflectionInfo.TypeReference.containsRemoteAddress(
|
||||||
|
remoteAddr, 1)) {
|
||||||
|
// possiblyMatchingTypeReference ends before remoteAddr, but it doesn't
|
||||||
|
// contain remoteAddr.
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// possiblyMatchingTypeReference contains remoteAddr.
|
||||||
|
return possiblyMatchingReflectionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
RemoteRef<char> TypeRefBuilder::ReflectionTypeDescriptorFinder::readTypeRef(
|
RemoteRef<char> TypeRefBuilder::ReflectionTypeDescriptorFinder::readTypeRef(
|
||||||
uint64_t remoteAddr) {
|
uint64_t remoteAddr) {
|
||||||
// The remote address should point into one of the TypeRef or
|
// The remote address should point into one of the TypeRef or
|
||||||
// ReflectionString references we already read out of the images.
|
// ReflectionString references we already read out of the images.
|
||||||
RemoteRef<char> foundTypeRef;
|
RemoteRef<char> foundTypeRef;
|
||||||
RemoteRef<void> limitAddress;
|
RemoteRef<void> limitAddress;
|
||||||
|
|
||||||
|
const auto infoWithTypeReferenceContainingAddress =
|
||||||
|
findReflectionInfoWithTypeRefContainingAddress(remoteAddr);
|
||||||
|
if (infoWithTypeReferenceContainingAddress.has_value()) {
|
||||||
|
foundTypeRef = infoWithTypeReferenceContainingAddress->get()
|
||||||
|
.TypeReference.getRemoteRef<char>(remoteAddr);
|
||||||
|
limitAddress = infoWithTypeReferenceContainingAddress->get()
|
||||||
|
.TypeReference.endAddress();
|
||||||
|
goto found_type_ref;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &info : ReflectionInfos) {
|
for (auto &info : ReflectionInfos) {
|
||||||
if (info.TypeReference.containsRemoteAddress(remoteAddr, 1)) {
|
|
||||||
foundTypeRef = info.TypeReference.getRemoteRef<char>(remoteAddr);
|
|
||||||
limitAddress = info.TypeReference.endAddress();
|
|
||||||
goto found_type_ref;
|
|
||||||
}
|
|
||||||
if (info.ReflectionString.containsRemoteAddress(remoteAddr, 1)) {
|
if (info.ReflectionString.containsRemoteAddress(remoteAddr, 1)) {
|
||||||
foundTypeRef = info.ReflectionString.getRemoteRef<char>(remoteAddr);
|
foundTypeRef = info.ReflectionString.getRemoteRef<char>(remoteAddr);
|
||||||
limitAddress = info.ReflectionString.endAddress();
|
limitAddress = info.ReflectionString.endAddress();
|
||||||
|
|||||||
Reference in New Issue
Block a user