Skip to content

Commit b95820a

Browse files
committed
store edges in a map to dedup them
since it seems the GC sometimes traverses the same edge twice??
1 parent e9960d5 commit b95820a

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

src/gc-heap-snapshot.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ struct Node {
8484
// https://github.com/nodejs/from_node/blob/5fd7a72e1c4fbaf37d3723c4c81dce35c149dc84/deps/v8/include/v8-profiler.h#L739-L745
8585
int detachedness; // 0 - unknown, 1 - attached; 2 - detached
8686

87-
// Book-keeping fields (not used for serialization)
88-
vector<Edge> edges; // For asserting that we built the edges in the right order
87+
// edges outward from this node
88+
// keyed by the memory address of the object we're pointing outward to
89+
unordered_map<void *, Edge> edges;
8990
};
9091

9192

@@ -194,7 +195,7 @@ void _add_internal_root(HeapSnapshot *snapshot) {
194195
0, // int detachedness; // 0 - unknown, 1 - attached; 2 - detached
195196

196197
// outgoing edges
197-
vector<Edge>(),
198+
unordered_map<void *, Edge>(),
198199
};
199200
snapshot->nodes.push_back(internal_root);
200201
}
@@ -262,7 +263,7 @@ void record_node_to_gc_snapshot(jl_value_t *a) JL_NOTSAFEPOINT {
262263
0, // int detachedness; // 0 - unknown, 1 - attached; 2 - detached
263264

264265
// outgoing edges
265-
vector<Edge>(),
266+
unordered_map<void *, Edge>(),
266267
};
267268
g_snapshot->nodes.push_back(from_node);
268269
}
@@ -277,11 +278,11 @@ void _gc_heap_snapshot_record_root(jl_value_t *root, char *name) {
277278
auto edge_type = g_snapshot->edge_types.find_or_create_string_id("internal");
278279
auto edge_label = g_snapshot->names.find_or_create_string_id(name);
279280

280-
internal_root.edges.push_back(Edge{
281+
internal_root.edges[(void*)root] = Edge{
281282
edge_type,
282283
edge_label,
283284
to_node_idx,
284-
});
285+
};
285286

286287
g_snapshot->num_edges++;
287288
}
@@ -346,11 +347,11 @@ static inline void _record_gc_edge(const char *node_type, const char *edge_type,
346347
// TODO: can these ever disagree?:
347348
from_node.type = g_snapshot->node_types.find_or_create_string_id(node_type);
348349

349-
from_node.edges.push_back(Edge{
350+
from_node.edges[(void*)b] = Edge{
350351
g_snapshot->edge_types.find_or_create_string_id(edge_type),
351352
name_or_index,
352353
g_snapshot->node_ptr_to_index_map[b], // to
353-
});
354+
};
354355

355356
g_snapshot->num_edges += 1;
356357
count_edges += 1; // debugging
@@ -398,7 +399,8 @@ void serialize_heap_snapshot(JL_STREAM *stream, HeapSnapshot &snapshot) {
398399
jl_printf(stream, "\"edges\":[");
399400
bool first_edge = true;
400401
for (const auto &from_node : snapshot.nodes) {
401-
for (const auto &edge : from_node.edges) {
402+
for (const auto &address_and_edge : from_node.edges) {
403+
auto edge = address_and_edge.second;
402404
if (first_edge) {
403405
first_edge = false;
404406
} else {

0 commit comments

Comments
 (0)