Skip to content

Commit 39d4e01

Browse files
authored
Merge pull request #33487 from mikeash/concurrenthashmap
[Runtime] Reimplement protocol conformance cache with a hash table
2 parents 5a1f38b + ecd6d4d commit 39d4e01

File tree

14 files changed

+1483
-238
lines changed

14 files changed

+1483
-238
lines changed

Diff for: include/swift/Reflection/ReflectionContext.h

+49-2
Original file line numberDiff line numberDiff line change
@@ -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

Diff for: include/swift/Reflection/RuntimeInternals.h

+14
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ template <typename Runtime> struct MetadataCacheNode {
4646
typename Runtime::StoredPointer Right;
4747
};
4848

49+
template <typename Runtime> struct ConcurrentHashMap {
50+
typename Runtime::StoredSize ReaderCount;
51+
typename Runtime::StoredSize ElementCount;
52+
typename Runtime::StoredPointer Elements;
53+
typename Runtime::StoredPointer Indices;
54+
// We'll ignore the remaining fields for now....
55+
};
56+
57+
template <typename Runtime> struct ConformanceCacheEntry {
58+
typename Runtime::StoredPointer Type;
59+
typename Runtime::StoredPointer Proto;
60+
typename Runtime::StoredPointer Witness;
61+
};
62+
4963
} // end namespace reflection
5064
} // end namespace swift
5165

0 commit comments

Comments
 (0)