@@ -879,7 +879,8 @@ class ReflectionContext
879
879
std::function<void (StoredPointer Type, StoredPointer Proto)> Call) {
880
880
if (!NodePtr)
881
881
return ;
882
- auto NodeBytes = getReader ().readBytes (RemoteAddress (NodePtr), sizeof (Node));
882
+ auto NodeBytes = getReader ().readBytes (RemoteAddress (NodePtr),
883
+ sizeof (ConformanceNode<Runtime>));
883
884
auto NodeData =
884
885
reinterpret_cast <const ConformanceNode<Runtime> *>(NodeBytes.get ());
885
886
if (!NodeData)
@@ -889,6 +890,33 @@ class ReflectionContext
889
890
iterateConformanceTree (NodeData->Right , Call);
890
891
}
891
892
893
+ void IterateConformanceTable (
894
+ RemoteAddress ConformancesPtr,
895
+ std::function<void (StoredPointer Type, StoredPointer Proto)> Call) {
896
+ auto MapBytes = getReader ().readBytes (RemoteAddress (ConformancesPtr),
897
+ sizeof (ConcurrentHashMap<Runtime>));
898
+ auto MapData =
899
+ reinterpret_cast <const ConcurrentHashMap<Runtime> *>(MapBytes.get ());
900
+ if (!MapData)
901
+ return ;
902
+
903
+ auto Count = MapData->ElementCount ;
904
+ auto Size = Count * sizeof (ConformanceCacheEntry<Runtime>);
905
+
906
+ auto ElementsBytes =
907
+ getReader ().readBytes (RemoteAddress (MapData->Elements ), Size );
908
+ auto ElementsData =
909
+ reinterpret_cast <const ConformanceCacheEntry<Runtime> *>(
910
+ ElementsBytes.get ());
911
+ if (!ElementsData)
912
+ return ;
913
+
914
+ for (StoredSize i = 0 ; i < Count; i++) {
915
+ auto &Element = ElementsData[i];
916
+ Call (Element.Type , Element.Proto );
917
+ }
918
+ }
919
+
892
920
// / Iterate the protocol conformance cache in the target process, calling Call
893
921
// / with the type and protocol of each conformance. Returns None on success,
894
922
// / and a string describing the error on failure.
@@ -908,7 +936,26 @@ class ReflectionContext
908
936
909
937
auto Root = getReader ().readPointer (ConformancesAddr->getResolvedAddress (),
910
938
sizeof (StoredPointer));
911
- iterateConformanceTree (Root->getResolvedAddress ().getAddressData (), Call);
939
+ auto ReaderCount = Root->getResolvedAddress ().getAddressData ();
940
+
941
+ // ReaderCount will be the root pointer if the conformance cache is a
942
+ // ConcurrentMap. It's very unlikely that there would ever be more readers
943
+ // than the least valid pointer value, so compare with that to distinguish.
944
+ // TODO: once the old conformance cache is gone for good, remove that code.
945
+ uint64_t LeastValidPointerValue;
946
+ if (!getReader ().queryDataLayout (
947
+ DataLayoutQueryType::DLQ_GetLeastValidPointerValue, nullptr ,
948
+ &LeastValidPointerValue)) {
949
+ return std::string (" unable to query least valid pointer value" );
950
+ }
951
+
952
+ if (ReaderCount < LeastValidPointerValue)
953
+ IterateConformanceTable (ConformancesAddr->getResolvedAddress (), Call);
954
+ else {
955
+ // The old code has the root address at this location.
956
+ auto RootAddr = ReaderCount;
957
+ iterateConformanceTree (RootAddr, Call);
958
+ }
912
959
return llvm::None;
913
960
}
914
961
0 commit comments