@@ -37,18 +37,83 @@ TypeRefBuilder::decodeMangledType(Node *node, bool forRequirement) {
37
37
.getType ();
38
38
}
39
39
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
+
40
99
RemoteRef<char > TypeRefBuilder::ReflectionTypeDescriptorFinder::readTypeRef (
41
100
uint64_t remoteAddr) {
42
101
// The remote address should point into one of the TypeRef or
43
102
// ReflectionString references we already read out of the images.
44
103
RemoteRef<char > foundTypeRef;
45
104
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
+
46
116
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
- }
52
117
if (info.ReflectionString .containsRemoteAddress (remoteAddr, 1 )) {
53
118
foundTypeRef = info.ReflectionString .getRemoteRef <char >(remoteAddr);
54
119
limitAddress = info.ReflectionString .endAddress ();
0 commit comments