@@ -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) 
536536static  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