11use rustc_data_structures:: sync:: worker:: { Worker , WorkerExecutor } ;
22use rustc_data_structures:: sync:: { Lrc , AtomicCell } ;
33use rustc_data_structures:: { unlikely, cold_path} ;
4- use rustc_data_structures:: indexed_vec:: IndexVec ;
4+ use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
55use rustc_data_structures:: fingerprint:: Fingerprint ;
66use rustc_data_structures:: fx:: FxHashMap ;
77use rustc_serialize:: { Decodable , Encodable , Encoder , Decoder , opaque} ;
@@ -14,15 +14,158 @@ use crate::dep_graph::dep_node::{DepKind, DepNode};
1414use super :: prev:: PreviousDepGraph ;
1515use super :: graph:: { DepNodeData , DepNodeIndex , DepNodeState } ;
1616
17+ // calcutale a list of bytes to copy from the previous graph
18+
19+ fn decode_bounds (
20+ d : & mut opaque:: Decoder < ' _ > ,
21+ f : impl FnOnce ( & mut opaque:: Decoder < ' _ > ) -> Result < ( ) , String >
22+ ) -> Result < ( usize , usize ) , String > {
23+ let start = d. position ( ) ;
24+ f ( d) ?;
25+ Ok ( ( start, d. position ( ) ) )
26+ }
27+
28+ type NodePoisitions = Vec < Option < ( usize , usize ) > > ;
29+
30+ fn read_dep_graph_positions (
31+ d : & mut opaque:: Decoder < ' _ > ,
32+ result : & DecodedDepGraph ,
33+ ) -> Result < ( NodePoisitions , NodePoisitions ) , String > {
34+ let node_count = result. prev_graph . nodes . len ( ) ;
35+ let mut nodes: NodePoisitions = repeat ( None ) . take ( node_count) . collect ( ) ;
36+ let mut edges: NodePoisitions = repeat ( None ) . take ( node_count) . collect ( ) ;
37+
38+ loop {
39+ if d. position ( ) == d. data . len ( ) {
40+ break ;
41+ }
42+ match SerializedAction :: decode ( d) ? {
43+ SerializedAction :: AllocateNodes => {
44+ let len = d. read_u32 ( ) ?;
45+ let start = DepNodeIndex :: decode ( d) ?. as_u32 ( ) ;
46+ for i in 0 ..len {
47+ let i = ( start + i) as usize ;
48+ nodes[ i] = Some ( decode_bounds ( d, |d| DepNode :: decode ( d) . map ( |_| ( ) ) ) ?) ;
49+ edges[ i] = Some ( decode_bounds ( d, |d| {
50+ let len = d. read_u32 ( ) ?;
51+ for _ in 0 ..len {
52+ DepNodeIndex :: decode ( d) ?;
53+ }
54+ Ok ( ( ) )
55+ } ) ?) ;
56+ }
57+ }
58+ SerializedAction :: UpdateEdges => {
59+ let len = d. read_u32 ( ) ?;
60+ for _ in 0 ..len {
61+ let i = DepNodeIndex :: decode ( d) ?. as_u32 ( ) as usize ;
62+ edges[ i] = Some ( decode_bounds ( d, |d| {
63+ let len = d. read_u32 ( ) ?;
64+ for _ in 0 ..len {
65+ DepNodeIndex :: decode ( d) ?;
66+ }
67+ Ok ( ( ) )
68+ } ) ?) ;
69+ }
70+ }
71+ SerializedAction :: InvalidateNodes => {
72+ let len = d. read_u32 ( ) ?;
73+ for _ in 0 ..len {
74+ let i = DepNodeIndex :: decode ( d) ?. as_u32 ( ) as usize ;
75+ nodes[ i] = None ;
76+ edges[ i] = None ;
77+ }
78+ }
79+ }
80+ }
81+
82+ Ok ( ( nodes, edges) )
83+ }
84+
85+ pub fn gc_dep_graph (
86+ time_passes : bool ,
87+ d : & mut opaque:: Decoder < ' _ > ,
88+ result : & DecodedDepGraph ,
89+ file : & mut File ,
90+ ) {
91+ let ( nodes, edges) = time_ext ( time_passes, None , "read dep-graph positions" , || {
92+ read_dep_graph_positions ( d, result) . unwrap ( )
93+ } ) ;
94+
95+ let mut i = 0 ;
96+
97+ loop {
98+ // Skip empty nodes
99+ while i < nodes. len ( ) && nodes[ i] . is_none ( ) {
100+ i += 1 ;
101+ }
102+
103+ // Break if we are done
104+ if i >= nodes. len ( ) {
105+ break ;
106+ }
107+
108+ // Find out how many consecutive nodes we will emit
109+ let mut len = 1 ;
110+ while i + len < nodes. len ( ) && nodes[ i + len] . is_some ( ) {
111+ len += 1 ;
112+ }
113+
114+ let mut encoder = opaque:: Encoder :: new ( Vec :: with_capacity ( 11 ) ) ;
115+ SerializedAction :: AllocateNodes . encode ( & mut encoder) . ok ( ) ;
116+ // Emit the number of nodes we're emitting
117+ encoder. emit_u32 ( len as u32 ) . ok ( ) ;
118+
119+ // Emit the dep node index of the first node
120+ DepNodeIndex :: new ( i) . encode ( & mut encoder) . ok ( ) ;
121+
122+ file. write_all ( & encoder. into_inner ( ) ) . unwrap ( ) ;
123+
124+ let mut buffers = Vec :: with_capacity ( nodes. len ( ) * 2 ) ;
125+
126+ let push_buffer = |buffers : & mut Vec < ( usize , usize ) > , range : ( usize , usize ) | {
127+ if let Some ( last) = buffers. last_mut ( ) {
128+ if last. 1 == range. 0 {
129+ // Extend the last range
130+ last. 1 = range. 1 ;
131+ return ;
132+ }
133+ }
134+ buffers. push ( range) ;
135+ } ;
136+
137+ for i in i..( i + len) {
138+ // Encode the node
139+ push_buffer ( & mut buffers, nodes[ i] . unwrap ( ) ) ;
140+
141+ // Encode dependencies
142+ push_buffer ( & mut buffers, edges[ i] . unwrap ( ) ) ;
143+ }
144+
145+ for buffer in buffers {
146+ file. write_all ( & d. data [ buffer. 0 ..buffer. 1 ] ) . unwrap ( ) ;
147+ }
148+
149+ i += len;
150+ }
151+ }
152+
153+ pub struct DecodedDepGraph {
154+ pub prev_graph : PreviousDepGraph ,
155+ pub state : IndexVec < DepNodeIndex , AtomicCell < DepNodeState > > ,
156+ pub invalidated : Vec < DepNodeIndex > ,
157+ pub needs_gc : bool ,
158+ }
159+
17160pub fn decode_dep_graph (
18161 time_passes : bool ,
19162 d : & mut opaque:: Decoder < ' _ > ,
20163 results_d : & mut opaque:: Decoder < ' _ > ,
21- ) -> Result < (
22- PreviousDepGraph ,
23- IndexVec < DepNodeIndex , AtomicCell < DepNodeState > > ,
24- Vec < DepNodeIndex > ,
25- ) , String > {
164+ ) -> Result < DecodedDepGraph , String > {
165+ // Metrics used to decided when to GC
166+ let mut valid_data = 0 ;
167+ let mut total_data = 0 ;
168+
26169 let fingerprints: IndexVec < DepNodeIndex , Fingerprint > =
27170 time_ext ( time_passes, None , "decode prev result fingerprints" , || {
28171 IndexVec :: decode ( results_d)
@@ -35,7 +178,6 @@ pub fn decode_dep_graph(
35178 let mut state: IndexVec < _ , _ > = ( 0 ..fingerprints. len ( ) ) . map ( |_| {
36179 AtomicCell :: new ( DepNodeState :: Invalid )
37180 } ) . collect ( ) ;
38- let mut invalid = Vec :: new ( ) ;
39181 loop {
40182 if d. position ( ) == d. data . len ( ) {
41183 break ;
@@ -48,29 +190,39 @@ pub fn decode_dep_graph(
48190 let i = DepNodeIndex :: from_u32 ( start + i) ;
49191 let node = DepNode :: decode ( d) ?;
50192 nodes[ i] = node;
51- edges[ i] = Some ( Box :: < [ DepNodeIndex ] > :: decode ( d) ?) ;
193+ let node_edges = Box :: < [ DepNodeIndex ] > :: decode ( d) ?;
194+ valid_data += node_edges. len ( ) ;
195+ total_data += node_edges. len ( ) ;
196+ edges[ i] = Some ( node_edges) ;
52197
53198 if unlikely ! ( node. kind. is_eval_always( ) ) {
54199 state[ i] = AtomicCell :: new ( DepNodeState :: UnknownEvalAlways ) ;
55200 } else {
56201 state[ i] = AtomicCell :: new ( DepNodeState :: Unknown ) ;
57202 }
58203 }
204+ valid_data += len as usize * 8 ;
205+ total_data += len as usize * 8 ;
59206 }
60207 SerializedAction :: UpdateEdges => {
61208 let len = d. read_u32 ( ) ?;
62209 for _ in 0 ..len {
63210 let i = DepNodeIndex :: decode ( d) ?;
64- edges[ i] = Some ( Box :: < [ DepNodeIndex ] > :: decode ( d) ?) ;
211+ valid_data -= edges[ i] . as_ref ( ) . map_or ( 0 , |edges| edges. len ( ) ) ;
212+ let node_edges = Box :: < [ DepNodeIndex ] > :: decode ( d) ?;
213+ valid_data += node_edges. len ( ) ;
214+ total_data += node_edges. len ( ) ;
215+ edges[ i] = Some ( node_edges) ;
65216 }
66217 }
67218 SerializedAction :: InvalidateNodes => {
68219 let len = d. read_u32 ( ) ?;
69220 for _ in 0 ..len {
70221 let i = DepNodeIndex :: decode ( d) ?;
222+ valid_data -= edges[ i] . as_ref ( ) . map_or ( 0 , |edges| edges. len ( ) ) ;
71223 state[ i] = AtomicCell :: new ( DepNodeState :: Invalid ) ;
72- invalid. push ( i) ;
73224 }
225+ valid_data -= len as usize * 8 ;
74226 }
75227 }
76228 }
@@ -81,12 +233,27 @@ pub fn decode_dep_graph(
81233 . map ( |( idx, dep_node) | ( * dep_node, idx) )
82234 . collect ( )
83235 } ) ;
84- Ok ( ( PreviousDepGraph {
85- index,
86- nodes,
87- fingerprints,
88- edges,
89- } , state, invalid) )
236+
237+ debug ! (
238+ "valid bytes {} total bytes {} ratio {}" ,
239+ valid_data,
240+ total_data,
241+ valid_data as f32 / total_data as f32
242+ ) ;
243+
244+ Ok ( DecodedDepGraph {
245+ prev_graph : PreviousDepGraph {
246+ index,
247+ nodes,
248+ fingerprints,
249+ edges,
250+ } ,
251+ invalidated : state. indices ( )
252+ . filter ( |& i| * state[ i] . get_mut ( ) == DepNodeState :: Invalid )
253+ . collect ( ) ,
254+ state,
255+ needs_gc : valid_data + valid_data / 3 < total_data,
256+ } )
90257}
91258
92259#[ derive( Debug , RustcDecodable , RustcEncodable ) ]
0 commit comments