Skip to content

Commit 68106bd

Browse files
authored
[Sample Profile Loader] Fix potential invalidated reference (llvm#73181)
There is a potential issue in ProfiledCallGraph where pointers to ProfiledCallGraphNode are used to construct edges, while ProfiledCallGraphNode instances are being added to a hash map ProfiledFunctions simultaneously. If rehash happens, those pointers are invalidated, resulting in undefined behavior/crash. Previously (before md5phase2) ProfiledFunctions is a llvm::StringMap, which also have the same issue theoretically when rehashing but was not observed. This patch fixes this potential issue by using a backing buffer for ProrfiledCallGraphNode that does not relocate.
1 parent f150ecc commit 68106bd

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,11 @@ class ProfiledCallGraph {
140140
if (!ProfiledFunctions.count(Name)) {
141141
// Link to synthetic root to make sure every node is reachable
142142
// from root. This does not affect SCC order.
143-
ProfiledFunctions[Name] = ProfiledCallGraphNode(Name);
144-
Root.Edges.emplace(&Root, &ProfiledFunctions[Name], 0);
143+
// Store the pointer of the node because the map can be rehashed.
144+
auto &Node =
145+
ProfiledCallGraphNodeList.emplace_back(ProfiledCallGraphNode(Name));
146+
ProfiledFunctions[Name] = &Node;
147+
Root.Edges.emplace(&Root, ProfiledFunctions[Name], 0);
145148
}
146149
}
147150

@@ -152,9 +155,9 @@ class ProfiledCallGraph {
152155
auto CalleeIt = ProfiledFunctions.find(CalleeName);
153156
if (CalleeIt == ProfiledFunctions.end())
154157
return;
155-
ProfiledCallGraphEdge Edge(&ProfiledFunctions[CallerName],
156-
&CalleeIt->second, Weight);
157-
auto &Edges = ProfiledFunctions[CallerName].Edges;
158+
ProfiledCallGraphEdge Edge(ProfiledFunctions[CallerName],
159+
CalleeIt->second, Weight);
160+
auto &Edges = ProfiledFunctions[CallerName]->Edges;
158161
auto EdgeIt = Edges.find(Edge);
159162
if (EdgeIt == Edges.end()) {
160163
Edges.insert(Edge);
@@ -193,7 +196,7 @@ class ProfiledCallGraph {
193196
return;
194197

195198
for (auto &Node : ProfiledFunctions) {
196-
auto &Edges = Node.second.Edges;
199+
auto &Edges = Node.second->Edges;
197200
auto I = Edges.begin();
198201
while (I != Edges.end()) {
199202
if (I->Weight <= Threshold)
@@ -205,7 +208,9 @@ class ProfiledCallGraph {
205208
}
206209

207210
ProfiledCallGraphNode Root;
208-
HashKeyMap<std::unordered_map, FunctionId, ProfiledCallGraphNode>
211+
// backing buffer for ProfiledCallGraphNodes.
212+
std::list<ProfiledCallGraphNode> ProfiledCallGraphNodeList;
213+
HashKeyMap<llvm::DenseMap, FunctionId, ProfiledCallGraphNode*>
209214
ProfiledFunctions;
210215
};
211216

0 commit comments

Comments
 (0)