Skip to content

Commit 6fb1f1f

Browse files
authored
Do early deduplication
1 parent 30b0c82 commit 6fb1f1f

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

src/mono/mono/metadata/sgen-tarjan-bridge.c

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -534,10 +534,15 @@ find_in_cache (int *insert_index)
534534

535535
// Populate other_colors for a give color (other_colors represent the xrefs for this color)
536536
static void
537-
add_other_colors (ColorData *color, DynPtrArray *other_colors)
537+
add_other_colors (ColorData *color, DynPtrArray *other_colors, gboolean check_visited)
538538
{
539539
for (int i = 0; i < dyn_array_ptr_size (other_colors); ++i) {
540540
ColorData *points_to = (ColorData *)dyn_array_ptr_get (other_colors, i);
541+
if (check_visited) {
542+
if (points_to->visited)
543+
continue;
544+
points_to->visited = TRUE;
545+
}
541546
dyn_array_ptr_add (&color->other_colors, points_to);
542547
// Inform targets
543548
points_to->incoming_colors = MIN (points_to->incoming_colors + 1, INCOMING_COLORS_MAX);
@@ -561,7 +566,7 @@ new_color (gboolean has_bridges)
561566
cd = alloc_color_data ();
562567
cd->api_index = -1;
563568

564-
add_other_colors (cd, &color_merge_array);
569+
add_other_colors (cd, &color_merge_array, FALSE);
565570

566571
/* if cacheSlot >= 0, it means we prepared a given slot to receive the new color */
567572
if (cacheSlot >= 0)
@@ -748,7 +753,7 @@ create_scc (ScanData *data)
748753

749754
for (i = dyn_array_ptr_size (&loop_stack) - 1; i >= 0; --i) {
750755
ScanData *other = (ScanData *)dyn_array_ptr_get (&loop_stack, i);
751-
found_bridge |= other->is_bridge;
756+
found_bridge |= other->is_bridge || dyn_array_ptr_size (&other->xrefs) > 0;
752757
if (found_bridge || other == data)
753758
break;
754759
}
@@ -792,10 +797,17 @@ create_scc (ScanData *data)
792797
dyn_array_ptr_add (&color_data->bridges, other->obj);
793798
}
794799

795-
// Maybe we should make sure we are not adding duplicates here. It is not really a problem
796-
// since we will get rid of duplicates before submitting the SCCs to the client in gather_xrefs
797-
if (color_data)
798-
add_other_colors (color_data, &other->xrefs);
800+
if (color_data) {
801+
// We need to eliminate duplicates early otherwise the heaviness property
802+
// can change in gather_xrefs and it breaks down the loop that reports the
803+
// xrefs to the client.
804+
//
805+
// We reuse the visited flag to mark the objects that are already part of
806+
// the color_data array. The array was created above with the new_color call
807+
// and xrefs were populated from color_merge_array, which is already
808+
// deduplicated and every entry is marked as visited.
809+
add_other_colors (color_data, &other->xrefs, TRUE);
810+
}
799811
dyn_array_ptr_uninit (&other->xrefs);
800812

801813
if (other == data) {
@@ -805,6 +817,13 @@ create_scc (ScanData *data)
805817
}
806818
g_assert (found);
807819

820+
// Clear the visited flag on nodes that were added with add_other_colors in the loop above
821+
for (int i = dyn_array_ptr_size (&color_merge_array); i < dyn_array_ptr_size (&color_data->other_colors); i++) {
822+
ColorData *cd = (ColorData *)dyn_array_ptr_get (&color_data->other_colors, i);
823+
g_assert (cd->visited);
824+
cd->visited = FALSE;
825+
}
826+
808827
#if DUMP_GRAPH
809828
printf ("\tpoints-to-colors: ");
810829
for (int i = 0; i < dyn_array_ptr_size (&color_data->other_colors); i++)
@@ -1109,13 +1128,7 @@ processing_build_callback_data (int generation)
11091128
gather_xrefs (cd);
11101129
reset_xrefs (cd);
11111130
dyn_array_ptr_set_all (&cd->other_colors, &color_merge_array);
1112-
1113-
// Deduplicating the xrefs can cause the heaviness of this graph
1114-
// node to change. The duplicates can be introduced in create_scc,
1115-
// see comment there.
1116-
if (!color_visible_to_client (cd))
1117-
continue;
1118-
1131+
g_assert (color_visible_to_client (cd));
11191132
xref_count += dyn_array_ptr_size (&cd->other_colors);
11201133
}
11211134
}

0 commit comments

Comments
 (0)