@@ -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+
4099RemoteRef<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