@@ -74,7 +74,7 @@ struct DepGraphData {
7474     /// nodes and edges as well as all fingerprints of nodes that have them. 
7575     previous :  PreviousDepGraph , 
7676
77-     colors :  RefCell < FxHashMap < DepNode ,   DepNodeColor > > , 
77+     colors :  RefCell < DepNodeColorMap > , 
7878
7979    /// When we load, there may be `.o` files, cached mir, or other such 
8080     /// things available to us. If we find that they are not dirty, we 
@@ -97,16 +97,18 @@ impl DepGraph {
9797        // Pre-allocate the fingerprints array. We over-allocate a little so 
9898        // that we hopefully don't have to re-allocate during this compilation 
9999        // session. 
100+         let  prev_graph_node_count = prev_graph. node_count ( ) ; 
101+ 
100102        let  fingerprints = IndexVec :: from_elem_n ( Fingerprint :: ZERO , 
101-                                                  ( prev_graph . node_count ( )  *  115 )  / 100 ) ; 
103+                                                  ( prev_graph_node_count  *  115 )  / 100 ) ; 
102104        DepGraph  { 
103105            data :  Some ( Rc :: new ( DepGraphData  { 
104106                previous_work_products :  RefCell :: new ( FxHashMap ( ) ) , 
105107                work_products :  RefCell :: new ( FxHashMap ( ) ) , 
106108                dep_node_debug :  RefCell :: new ( FxHashMap ( ) ) , 
107109                current :  RefCell :: new ( CurrentDepGraph :: new ( ) ) , 
108110                previous :  prev_graph, 
109-                 colors :  RefCell :: new ( FxHashMap ( ) ) , 
111+                 colors :  RefCell :: new ( DepNodeColorMap :: new ( prev_graph_node_count ) ) , 
110112                loaded_from_cache :  RefCell :: new ( FxHashMap ( ) ) , 
111113            } ) ) , 
112114            fingerprints :  Rc :: new ( RefCell :: new ( fingerprints) ) , 
@@ -213,8 +215,6 @@ impl DepGraph {
213215              R :  HashStable < HCX > , 
214216    { 
215217        if  let  Some ( ref  data)  = self . data  { 
216-             debug_assert ! ( !data. colors. borrow( ) . contains_key( & key) ) ; 
217- 
218218            push ( & data. current ,  key) ; 
219219            if  cfg ! ( debug_assertions)  { 
220220                profq_msg ( ProfileQueriesMsg :: TaskBegin ( key. clone ( ) ) ) 
@@ -254,19 +254,21 @@ impl DepGraph {
254254            } 
255255
256256            // Determine the color of the new DepNode. 
257-             { 
258-                 let  prev_fingerprint = data. previous . fingerprint_of ( & key ) ; 
257+             if   let   Some ( prev_index )  = data . previous . node_to_index_opt ( & key )   { 
258+                 let  prev_fingerprint = data. previous . fingerprint_by_index ( prev_index ) ; 
259259
260-                 let  color = if  Some ( current_fingerprint)  == prev_fingerprint { 
260+                 let  color = if  current_fingerprint == prev_fingerprint { 
261261                    DepNodeColor :: Green ( dep_node_index) 
262262                }  else  { 
263263                    DepNodeColor :: Red 
264264                } ; 
265265
266-                 let  old_value  = data. colors . borrow_mut ( ) . insert ( key ,  color ) ; 
267-                 debug_assert ! ( old_value . is_none( ) , 
266+                 let  mut  colors  = data. colors . borrow_mut ( ) ; 
267+                 debug_assert ! ( colors . get ( prev_index ) . is_none( ) , 
268268                              "DepGraph::with_task() - Duplicate DepNodeColor \  
269269                                insertion for {:?}",  key) ; 
270+ 
271+                 colors. insert ( prev_index,  color) ; 
270272            } 
271273
272274            ( result,  dep_node_index) 
@@ -281,9 +283,11 @@ impl DepGraph {
281283                let  mut  fingerprints = self . fingerprints . borrow_mut ( ) ; 
282284                let  dep_node_index = DepNodeIndex :: new ( fingerprints. len ( ) ) ; 
283285                fingerprints. push ( fingerprint) ; 
286+ 
284287                debug_assert ! ( fingerprints[ dep_node_index]  == fingerprint, 
285288                              "DepGraph::with_task() - Assigned fingerprint to \  
286289                                unexpected index for {:?}",  key) ; 
290+ 
287291                ( result,  dep_node_index) 
288292            }  else  { 
289293                ( task ( cx,  arg) ,  DepNodeIndex :: INVALID ) 
@@ -356,6 +360,15 @@ impl DepGraph {
356360            . unwrap ( ) 
357361    } 
358362
363+     #[ inline]  
364+     pub  fn  dep_node_exists ( & self ,  dep_node :  & DepNode )  -> bool  { 
365+         if  let  Some ( ref  data)  = self . data  { 
366+             data. current . borrow_mut ( ) . node_to_node_index . contains_key ( dep_node) 
367+         }  else  { 
368+             false 
369+         } 
370+     } 
371+ 
359372    #[ inline]  
360373    pub  fn  fingerprint_of ( & self ,  dep_node_index :  DepNodeIndex )  -> Fingerprint  { 
361374        match  self . fingerprints . borrow ( ) . get ( dep_node_index)  { 
@@ -495,7 +508,17 @@ impl DepGraph {
495508    } 
496509
497510    pub  fn  node_color ( & self ,  dep_node :  & DepNode )  -> Option < DepNodeColor >  { 
498-         self . data . as_ref ( ) . and_then ( |data| data. colors . borrow ( ) . get ( dep_node) . cloned ( ) ) 
511+         if  let  Some ( ref  data)  = self . data  { 
512+             if  let  Some ( prev_index)  = data. previous . node_to_index_opt ( dep_node)  { 
513+                 return  data. colors . borrow ( ) . get ( prev_index) 
514+             }  else  { 
515+                 // This is a node that did not exist in the previous compilation 
516+                 // session, so we consider it to be red. 
517+                 return  Some ( DepNodeColor :: Red ) 
518+             } 
519+         } 
520+ 
521+         None 
499522    } 
500523
501524    pub  fn  try_mark_green < ' tcx > ( & self , 
@@ -505,7 +528,6 @@ impl DepGraph {
505528        debug ! ( "try_mark_green({:?}) - BEGIN" ,  dep_node) ; 
506529        let  data = self . data . as_ref ( ) . unwrap ( ) ; 
507530
508-         debug_assert ! ( !data. colors. borrow( ) . contains_key( dep_node) ) ; 
509531        debug_assert ! ( !data. current. borrow( ) . node_to_node_index. contains_key( dep_node) ) ; 
510532
511533        if  dep_node. kind . is_input ( )  { 
@@ -535,19 +557,22 @@ impl DepGraph {
535557            } 
536558        } ; 
537559
560+         debug_assert ! ( data. colors. borrow( ) . get( prev_dep_node_index) . is_none( ) ) ; 
561+ 
538562        let  mut  current_deps = Vec :: new ( ) ; 
539563
540564        for  & dep_dep_node_index in  prev_deps { 
541-             let  dep_dep_node  = & data. previous . index_to_node ( dep_dep_node_index) ; 
565+             let  dep_dep_node_color  = data. colors . borrow ( ) . get ( dep_dep_node_index) ; 
542566
543-             let  dep_dep_node_color = data. colors . borrow ( ) . get ( dep_dep_node) . cloned ( ) ; 
544567            match  dep_dep_node_color { 
545568                Some ( DepNodeColor :: Green ( node_index) )  => { 
546569                    // This dependency has been marked as green before, we are 
547570                    // still fine and can continue with checking the other 
548571                    // dependencies. 
549572                    debug ! ( "try_mark_green({:?}) --- found dependency {:?} to \  
550-                              be immediately green",  dep_node,  dep_dep_node) ; 
573+                              be immediately green", 
574+                             dep_node, 
575+                             data. previous. index_to_node( dep_dep_node_index) ) ; 
551576                    current_deps. push ( node_index) ; 
552577                } 
553578                Some ( DepNodeColor :: Red )  => { 
@@ -556,10 +581,14 @@ impl DepGraph {
556581                    // mark the DepNode as green and also don't need to bother 
557582                    // with checking any of the other dependencies. 
558583                    debug ! ( "try_mark_green({:?}) - END - dependency {:?} was \  
559-                              immediately red",  dep_node,  dep_dep_node) ; 
584+                              immediately red", 
585+                             dep_node, 
586+                             data. previous. index_to_node( dep_dep_node_index) ) ; 
560587                    return  None 
561588                } 
562589                None  => { 
590+                     let  dep_dep_node = & data. previous . index_to_node ( dep_dep_node_index) ; 
591+ 
563592                    // We don't know the state of this dependency. If it isn't 
564593                    // an input node, let's try to mark it green recursively. 
565594                    if  !dep_dep_node. kind . is_input ( )  { 
@@ -601,10 +630,8 @@ impl DepGraph {
601630                    debug ! ( "try_mark_green({:?}) --- trying to force \  
602631                             dependency {:?}",  dep_node,  dep_dep_node) ; 
603632                    if  :: ty:: maps:: force_from_dep_node ( tcx,  dep_dep_node)  { 
604-                         let  dep_dep_node_color = data. colors 
605-                                                      . borrow ( ) 
606-                                                      . get ( dep_dep_node) 
607-                                                      . cloned ( ) ; 
633+                         let  dep_dep_node_color = data. colors . borrow ( ) . get ( dep_dep_node_index) ; 
634+ 
608635                        match  dep_dep_node_color { 
609636                            Some ( DepNodeColor :: Green ( node_index) )  => { 
610637                                debug ! ( "try_mark_green({:?}) --- managed to \  
@@ -681,26 +708,21 @@ impl DepGraph {
681708        } 
682709
683710        // ... and finally storing a "Green" entry in the color map. 
684-         let  old_color = data. colors 
685-                             . borrow_mut ( ) 
686-                             . insert ( * dep_node,  DepNodeColor :: Green ( dep_node_index) ) ; 
687-         debug_assert ! ( old_color. is_none( ) , 
711+         let  mut  colors = data. colors . borrow_mut ( ) ; 
712+         debug_assert ! ( colors. get( prev_dep_node_index) . is_none( ) , 
688713                      "DepGraph::try_mark_green() - Duplicate DepNodeColor \  
689714                       insertion for {:?}",  dep_node) ; 
690715
716+         colors. insert ( prev_dep_node_index,  DepNodeColor :: Green ( dep_node_index) ) ; 
717+ 
691718        debug ! ( "try_mark_green({:?}) - END - successfully marked as green" ,  dep_node) ; 
692719        Some ( dep_node_index) 
693720    } 
694721
695-     // Used in various assertions 
696-     pub  fn  is_green ( & self ,  dep_node_index :  DepNodeIndex )  -> bool  { 
697-         let  dep_node = self . data . as_ref ( ) . unwrap ( ) . current . borrow ( ) . nodes [ dep_node_index] ; 
698-         self . data . as_ref ( ) . unwrap ( ) . colors . borrow ( ) . get ( & dep_node) . map ( |& color| { 
699-             match  color { 
700-                 DepNodeColor :: Red  => false , 
701-                 DepNodeColor :: Green ( _)  => true , 
702-             } 
703-         } ) . unwrap_or ( false ) 
722+     // Returns true if the given node has been marked as green during the 
723+     // current compilation session. Used in various assertions 
724+     pub  fn  is_green ( & self ,  dep_node :  & DepNode )  -> bool  { 
725+         self . node_color ( dep_node) . map ( |c| c. is_green ( ) ) . unwrap_or ( false ) 
704726    } 
705727
706728    // This method loads all on-disk cacheable query results into memory, so 
@@ -714,20 +736,25 @@ impl DepGraph {
714736    pub  fn  exec_cache_promotions < ' a ,  ' tcx > ( & self ,  tcx :  TyCtxt < ' a ,  ' tcx ,  ' tcx > )  { 
715737        let  green_nodes:  Vec < DepNode >  = { 
716738            let  data = self . data . as_ref ( ) . unwrap ( ) ; 
717-             data. colors . borrow ( ) . iter ( ) . filter_map ( |( dep_node,  color) | match  color { 
718-                 DepNodeColor :: Green ( _)  => { 
719-                     if  dep_node. cache_on_disk ( tcx)  { 
720-                         Some ( * dep_node) 
721-                     }  else  { 
739+             let  colors = data. colors . borrow ( ) ; 
740+             colors. values . indices ( ) . filter_map ( |prev_index| { 
741+                 match  colors. get ( prev_index)  { 
742+                     Some ( DepNodeColor :: Green ( _) )  => { 
743+                         let  dep_node = data. previous . index_to_node ( prev_index) ; 
744+                         if  dep_node. cache_on_disk ( tcx)  { 
745+                             Some ( dep_node) 
746+                         }  else  { 
747+                             None 
748+                         } 
749+                     } 
750+                     None  |
751+                     Some ( DepNodeColor :: Red )  => { 
752+                         // We can skip red nodes because a node can only be marked 
753+                         // as red if the query result was recomputed and thus is 
754+                         // already in memory. 
722755                        None 
723756                    } 
724757                } 
725-                 DepNodeColor :: Red  => { 
726-                     // We can skip red nodes because a node can only be marked 
727-                     // as red if the query result was recomputed and thus is 
728-                     // already in memory. 
729-                     None 
730-                 } 
731758            } ) . collect ( ) 
732759        } ; 
733760
@@ -1052,3 +1079,36 @@ enum OpenTask {
10521079        node :  DepNode , 
10531080    } , 
10541081} 
1082+ 
1083+ // A data structure that stores Option<DepNodeColor> values as a contiguous 
1084+ // array, using one u32 per entry. 
1085+ struct  DepNodeColorMap  { 
1086+     values :  IndexVec < SerializedDepNodeIndex ,  u32 > , 
1087+ } 
1088+ 
1089+ const  COMPRESSED_NONE :  u32  = 0 ; 
1090+ const  COMPRESSED_RED :  u32  = 1 ; 
1091+ const  COMPRESSED_FIRST_GREEN :  u32  = 2 ; 
1092+ 
1093+ impl  DepNodeColorMap  { 
1094+     fn  new ( size :  usize )  -> DepNodeColorMap  { 
1095+         DepNodeColorMap  { 
1096+             values :  IndexVec :: from_elem_n ( COMPRESSED_NONE ,  size) 
1097+         } 
1098+     } 
1099+ 
1100+     fn  get ( & self ,  index :  SerializedDepNodeIndex )  -> Option < DepNodeColor >  { 
1101+         match  self . values [ index]  { 
1102+             COMPRESSED_NONE  => None , 
1103+             COMPRESSED_RED  => Some ( DepNodeColor :: Red ) , 
1104+             value => Some ( DepNodeColor :: Green ( DepNodeIndex ( value - COMPRESSED_FIRST_GREEN ) ) ) 
1105+         } 
1106+     } 
1107+ 
1108+     fn  insert ( & mut  self ,  index :  SerializedDepNodeIndex ,  color :  DepNodeColor )  { 
1109+         self . values [ index]  = match  color { 
1110+             DepNodeColor :: Red  => COMPRESSED_RED , 
1111+             DepNodeColor :: Green ( index)  => index. 0  + COMPRESSED_FIRST_GREEN , 
1112+         } 
1113+     } 
1114+ } 
0 commit comments