11use rustc_data_structures:: sync:: worker:: { Worker , WorkerExecutor } ;
2- use rustc_data_structures:: sync:: Lrc ;
2+ use rustc_data_structures:: sync:: { Lrc , AtomicCell } ;
33use rustc_data_structures:: { unlikely, cold_path} ;
4- use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
5- use rustc_serialize :: opaque ;
6- use rustc_serialize:: { Decodable , Encodable } ;
4+ use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
5+ use rustc_data_structures :: fingerprint :: Fingerprint ;
6+ use rustc_serialize:: { Decodable , Encodable , opaque } ;
77use std:: mem;
88use std:: fs:: File ;
99use std:: io:: Write ;
10+ use crate :: dep_graph:: dep_node:: DepNode ;
11+ use super :: prev:: PreviousDepGraph ;
1012use super :: graph:: { DepNodeData , DepNodeIndex , DepNodeState } ;
1113
12- newtype_index ! {
13- pub struct SerializedDepNodeIndex { .. }
14- }
15-
16- impl SerializedDepNodeIndex {
17- pub fn current ( self ) -> DepNodeIndex {
18- DepNodeIndex :: from_u32 ( self . as_u32 ( ) )
19- }
20- }
21-
2214#[ derive( Debug , Default ) ]
2315pub struct SerializedDepGraph {
24- pub ( super ) nodes : IndexVec < DepNodeIndex , DepNodeData > ,
25- pub ( super ) state : IndexVec < DepNodeIndex , DepNodeState > ,
16+ pub ( super ) nodes : IndexVec < DepNodeIndex , SerializedDepNodeData > ,
17+ pub ( super ) fingerprints : IndexVec < DepNodeIndex , Fingerprint > ,
18+ }
19+
20+ #[ derive( Clone , Debug , RustcDecodable , RustcEncodable ) ]
21+ pub ( super ) struct SerializedDepNodeData {
22+ pub ( super ) node : DepNode ,
23+ pub ( super ) edges : Vec < DepNodeIndex > ,
2624}
2725
2826impl SerializedDepGraph {
29- pub fn decode ( d : & mut opaque:: Decoder < ' _ > ) -> Result < Self , String > {
30- let mut nodes = IndexVec :: new ( ) ;
31- let mut invalidated_list = Vec :: new ( ) ;
27+ pub fn decode (
28+ d : & mut opaque:: Decoder < ' _ > ,
29+ results_d : & mut opaque:: Decoder < ' _ > ,
30+ ) -> Result < ( Self , IndexVec < DepNodeIndex , AtomicCell < DepNodeState > > ) , String > {
31+ let fingerprints: IndexVec < DepNodeIndex , Fingerprint > = IndexVec :: decode ( results_d) ?;
32+ let mut nodes = IndexVec :: with_capacity ( fingerprints. len ( ) ) ;
33+ let mut state: IndexVec < _ , _ > = ( 0 ..fingerprints. len ( ) ) . map ( |_| {
34+ AtomicCell :: new ( DepNodeState :: Unknown )
35+ } ) . collect ( ) ;
3236 loop {
3337 if d. position ( ) == d. data . len ( ) {
3438 break ;
3539 }
36- match Action :: decode ( d) ? {
37- Action :: NewNodes ( new_nodes) => {
40+ match SerializedAction :: decode ( d) ? {
41+ SerializedAction :: NewNodes ( new_nodes) => {
42+ for ( i, data) in new_nodes. iter ( ) . enumerate ( ) {
43+ // Mark the result of eval_always nodes as invalid so they will
44+ // get executed again.
45+ if unlikely ! ( data. node. kind. is_eval_always( ) ) {
46+ let idx = DepNodeIndex :: new ( nodes. len ( ) + i) ;
47+ state[ idx] = AtomicCell :: new ( DepNodeState :: Invalid ) ;
48+ }
49+ }
3850 nodes. extend ( new_nodes) ;
3951 }
40- Action :: UpdateNodes ( changed) => {
41- for ( i, data) in changed {
42- nodes[ i] = data;
52+ SerializedAction :: UpdateEdges ( changed) => {
53+ for ( i, edges) in changed {
54+ // Updated results are valid again, except for eval_always nodes
55+ // which always start out invalid.
56+ if likely ! ( !nodes[ i] . node. kind. is_eval_always( ) ) {
57+ state[ i] = AtomicCell :: new ( DepNodeState :: Unknown ) ;
58+ }
59+ nodes[ i] . edges = edges;
4360 }
4461 }
45- Action :: InvalidateNodes ( nodes) => {
46- invalidated_list. extend ( nodes) ;
62+ SerializedAction :: InvalidateNodes ( nodes) => {
63+ for i in nodes {
64+ state[ i] = AtomicCell :: new ( DepNodeState :: Invalid ) ;
65+ }
4766 }
4867 }
4968 }
50- let mut state: IndexVec < _ , _ > = ( 0 ..nodes. len ( ) ) . map ( |_| {
51- DepNodeState :: Unknown
52- } ) . collect ( ) ;
53- for i in invalidated_list {
54- state[ i] = DepNodeState :: Invalidated ;
55- }
56- Ok ( SerializedDepGraph {
69+ Ok ( ( SerializedDepGraph {
5770 nodes,
58- state ,
59- } )
71+ fingerprints ,
72+ } , state ) )
6073 }
6174}
6275
63- #[ derive( Debug , RustcEncodable , RustcDecodable ) ]
76+ #[ derive( Debug , RustcDecodable , RustcEncodable ) ]
77+ enum SerializedAction {
78+ NewNodes ( Vec < SerializedDepNodeData > ) ,
79+ UpdateEdges ( Vec < ( DepNodeIndex , Vec < DepNodeIndex > ) > ) ,
80+ InvalidateNodes ( Vec < DepNodeIndex > )
81+ }
82+
83+ #[ derive( Debug ) ]
6484enum Action {
6585 NewNodes ( Vec < DepNodeData > ) ,
6686 UpdateNodes ( Vec < ( DepNodeIndex , DepNodeData ) > ) ,
@@ -73,36 +93,66 @@ enum Action {
7393}
7494
7595struct SerializerWorker {
96+ fingerprints : IndexVec < DepNodeIndex , Fingerprint > ,
97+ previous : Lrc < PreviousDepGraph > ,
7698 file : File ,
7799}
78100
79101impl Worker for SerializerWorker {
80102 type Message = ( usize , Action ) ;
81- type Result = ( ) ;
103+ type Result = IndexVec < DepNodeIndex , Fingerprint > ;
82104
83105 fn message ( & mut self , ( buffer_size_est, action) : ( usize , Action ) ) {
84106 let mut encoder = opaque:: Encoder :: new ( Vec :: with_capacity ( buffer_size_est * 5 ) ) ;
107+ let action = match action {
108+ Action :: UpdateNodes ( nodes) => {
109+ SerializedAction :: UpdateEdges ( nodes. into_iter ( ) . filter ( |& ( i, ref data) | {
110+ self . fingerprints [ i] = data. fingerprint ;
111+ // Only emit nodes which actually changed
112+ & * data. edges != self . previous . edge_targets_from ( i)
113+ } ) . map ( |( i, data) | ( i, data. edges . into_iter ( ) . collect :: < Vec < _ > > ( ) ) ) . collect ( ) )
114+ }
115+ Action :: NewNodes ( nodes) => {
116+ SerializedAction :: NewNodes ( nodes. into_iter ( ) . map ( |data| {
117+ self . fingerprints . push ( data. fingerprint ) ;
118+ SerializedDepNodeData {
119+ node : data. node ,
120+ edges : data. edges . into_iter ( ) . collect ( ) ,
121+ }
122+ } ) . collect ( ) )
123+ }
124+ Action :: InvalidateNodes ( nodes) => SerializedAction :: InvalidateNodes ( nodes) ,
125+ } ;
85126 action. encode ( & mut encoder) . ok ( ) ;
86127 self . file . write_all ( & encoder. into_inner ( ) ) . expect ( "unable to write to temp dep graph" ) ;
87128 }
88129
89- fn complete ( self ) { }
130+ fn complete ( self ) -> IndexVec < DepNodeIndex , Fingerprint > {
131+ self . fingerprints
132+ }
90133}
91134
92135const BUFFER_SIZE : usize = 800000 ;
93136
94137pub struct Serializer {
95138 worker : Lrc < WorkerExecutor < SerializerWorker > > ,
139+ node_count : u32 ,
96140 new_buffer : Vec < DepNodeData > ,
97141 new_buffer_size : usize ,
98142 updated_buffer : Vec < ( DepNodeIndex , DepNodeData ) > ,
99143 updated_buffer_size : usize ,
100144}
101145
102146impl Serializer {
103- pub fn new ( file : File ) -> Self {
147+ pub fn new (
148+ file : File ,
149+ previous : Lrc < PreviousDepGraph > ,
150+ ) -> Self {
104151 Serializer {
152+ node_count : previous. node_count ( ) as u32 ,
105153 worker : Lrc :: new ( WorkerExecutor :: new ( SerializerWorker {
154+ fingerprints : previous. fingerprints . clone ( ) ,
155+ previous,
106156 file,
107157 } ) ) ,
108158 new_buffer : Vec :: with_capacity ( BUFFER_SIZE ) ,
@@ -120,7 +170,7 @@ impl Serializer {
120170 }
121171
122172 #[ inline]
123- pub ( super ) fn serialize_new ( & mut self , data : DepNodeData ) {
173+ pub ( super ) fn serialize_new ( & mut self , data : DepNodeData ) -> DepNodeIndex {
124174 let edges = data. edges . len ( ) ;
125175 self . new_buffer . push ( data) ;
126176 self . new_buffer_size += 8 + edges;
@@ -129,6 +179,9 @@ impl Serializer {
129179 self . flush_new ( ) ;
130180 } )
131181 }
182+ let index = self . node_count ;
183+ self . node_count += 1 ;
184+ DepNodeIndex :: from_u32 ( index)
132185 }
133186
134187 fn flush_updated ( & mut self ) {
@@ -153,7 +206,7 @@ impl Serializer {
153206 pub fn complete (
154207 & mut self ,
155208 invalidate : Vec < DepNodeIndex > ,
156- ) {
209+ ) -> IndexVec < DepNodeIndex , Fingerprint > {
157210 if self . new_buffer . len ( ) > 0 {
158211 self . flush_new ( ) ;
159212 }
0 commit comments