@@ -186,6 +186,11 @@ struct ColorData
186186 // Count of colors that list this color in their otherColors
187187 unsigned incomingColors : INCOMING_COLORS_BITS;
188188 unsigned visited : 1 ;
189+ // ColorVisibleToClient for a ColorData* can change over the course of bridge processing which
190+ // is problematic. We fix this by setting this flag when a color is detected as visible to client.
191+ // Once the flag is set, the color is pinned to being visible to client, even though it could lose
192+ // some xrefs, making it not satisfy the BridgelessColorIsHeavy condition.
193+ unsigned visibleToClient : 1 ;
189194};
190195
191196// Represents one managed object. Equivalent of new/old bridge "HashEntry"
@@ -233,7 +238,19 @@ static bool BridgelessColorIsHeavy(ColorData* data)
233238// Should color be made visible to client?
234239static bool ColorVisibleToClient (ColorData* data)
235240{
236- return DynPtrArraySize (&data->bridges ) || BridgelessColorIsHeavy (data);
241+ if (data->visibleToClient )
242+ return true ;
243+
244+ if (DynPtrArraySize (&data->bridges ) || BridgelessColorIsHeavy (data))
245+ {
246+ data->visibleToClient = true ;
247+ return true ;
248+ }
249+ else
250+ {
251+ return true ;
252+ }
253+
237254}
238255
239256// Stacks of ScanData objects used for tarjan algorithm.
@@ -1186,9 +1203,9 @@ static MarkCrossReferencesArgs* BuildSccCallbackData()
11861203 ColorData* cd;
11871204 for (cd = &cur->data [0 ]; cd < cur->nextData ; cd++)
11881205 {
1189- int bridges = DynPtrArraySize (&cd->bridges );
1190- if (!(bridges || BridgelessColorIsHeavy (cd)))
1206+ if (!ColorVisibleToClient (cd))
11911207 continue ;
1208+ int bridges = DynPtrArraySize (&cd->bridges );
11921209
11931210 apiSccs[apiIndex].Count = bridges;
11941211 uintptr_t *contexts = new (nothrow) uintptr_t [bridges];
0 commit comments