1
1
use rustc_data_structures:: sync:: worker:: { Worker , WorkerExecutor } ;
2
2
use rustc_data_structures:: sync:: { Lrc , AtomicCell } ;
3
3
use rustc_data_structures:: { unlikely, cold_path} ;
4
- use rustc_data_structures:: indexed_vec:: IndexVec ;
4
+ use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
5
5
use rustc_data_structures:: fingerprint:: Fingerprint ;
6
6
use rustc_data_structures:: fx:: FxHashMap ;
7
7
use rustc_serialize:: { Decodable , Encodable , Encoder , Decoder , opaque} ;
@@ -14,15 +14,158 @@ use crate::dep_graph::dep_node::{DepKind, DepNode};
14
14
use super :: prev:: PreviousDepGraph ;
15
15
use super :: graph:: { DepNodeData , DepNodeIndex , DepNodeState } ;
16
16
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
+
17
160
pub fn decode_dep_graph (
18
161
time_passes : bool ,
19
162
d : & mut opaque:: Decoder < ' _ > ,
20
163
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
+
26
169
let fingerprints: IndexVec < DepNodeIndex , Fingerprint > =
27
170
time_ext ( time_passes, None , "decode prev result fingerprints" , || {
28
171
IndexVec :: decode ( results_d)
@@ -35,7 +178,6 @@ pub fn decode_dep_graph(
35
178
let mut state: IndexVec < _ , _ > = ( 0 ..fingerprints. len ( ) ) . map ( |_| {
36
179
AtomicCell :: new ( DepNodeState :: Invalid )
37
180
} ) . collect ( ) ;
38
- let mut invalid = Vec :: new ( ) ;
39
181
loop {
40
182
if d. position ( ) == d. data . len ( ) {
41
183
break ;
@@ -48,29 +190,39 @@ pub fn decode_dep_graph(
48
190
let i = DepNodeIndex :: from_u32 ( start + i) ;
49
191
let node = DepNode :: decode ( d) ?;
50
192
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) ;
52
197
53
198
if unlikely ! ( node. kind. is_eval_always( ) ) {
54
199
state[ i] = AtomicCell :: new ( DepNodeState :: UnknownEvalAlways ) ;
55
200
} else {
56
201
state[ i] = AtomicCell :: new ( DepNodeState :: Unknown ) ;
57
202
}
58
203
}
204
+ valid_data += len as usize * 8 ;
205
+ total_data += len as usize * 8 ;
59
206
}
60
207
SerializedAction :: UpdateEdges => {
61
208
let len = d. read_u32 ( ) ?;
62
209
for _ in 0 ..len {
63
210
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) ;
65
216
}
66
217
}
67
218
SerializedAction :: InvalidateNodes => {
68
219
let len = d. read_u32 ( ) ?;
69
220
for _ in 0 ..len {
70
221
let i = DepNodeIndex :: decode ( d) ?;
222
+ valid_data -= edges[ i] . as_ref ( ) . map_or ( 0 , |edges| edges. len ( ) ) ;
71
223
state[ i] = AtomicCell :: new ( DepNodeState :: Invalid ) ;
72
- invalid. push ( i) ;
73
224
}
225
+ valid_data -= len as usize * 8 ;
74
226
}
75
227
}
76
228
}
@@ -81,12 +233,27 @@ pub fn decode_dep_graph(
81
233
. map ( |( idx, dep_node) | ( * dep_node, idx) )
82
234
. collect ( )
83
235
} ) ;
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
+ } )
90
257
}
91
258
92
259
#[ derive( Debug , RustcDecodable , RustcEncodable ) ]
0 commit comments