@@ -879,7 +879,8 @@ class ReflectionContext
879879 std::function<void (StoredPointer Type, StoredPointer Proto)> Call) {
880880 if (!NodePtr)
881881 return ;
882- auto NodeBytes = getReader ().readBytes (RemoteAddress (NodePtr), sizeof (Node));
882+ auto NodeBytes = getReader ().readBytes (RemoteAddress (NodePtr),
883+ sizeof (ConformanceNode<Runtime>));
883884 auto NodeData =
884885 reinterpret_cast <const ConformanceNode<Runtime> *>(NodeBytes.get ());
885886 if (!NodeData)
@@ -889,6 +890,33 @@ class ReflectionContext
889890 iterateConformanceTree (NodeData->Right , Call);
890891 }
891892
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+
892920 // / Iterate the protocol conformance cache in the target process, calling Call
893921 // / with the type and protocol of each conformance. Returns None on success,
894922 // / and a string describing the error on failure.
@@ -908,7 +936,26 @@ class ReflectionContext
908936
909937 auto Root = getReader ().readPointer (ConformancesAddr->getResolvedAddress (),
910938 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+ }
912959 return llvm::None;
913960 }
914961
0 commit comments