@@ -3,82 +3,100 @@ use rustc_data_structures::sync::Lrc;
3
3
use rustc_data_structures:: { unlikely, cold_path} ;
4
4
use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
5
5
use rustc_serialize:: opaque;
6
- use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
6
+ use rustc_serialize:: { Decodable , Encodable } ;
7
7
use std:: mem;
8
8
use std:: fs:: File ;
9
9
use std:: io:: Write ;
10
- use super :: graph:: DepNodeData ;
11
- use crate :: dep_graph:: DepNode ;
12
- use crate :: ich:: Fingerprint ;
10
+ use super :: graph:: { DepNodeData , DepNodeIndex , DepNodeState } ;
13
11
14
12
newtype_index ! {
15
13
pub struct SerializedDepNodeIndex { .. }
16
14
}
17
15
18
- /// Data for use when recompiling the **current crate**.
16
+ impl SerializedDepNodeIndex {
17
+ pub fn current ( self ) -> DepNodeIndex {
18
+ DepNodeIndex :: from_u32 ( self . as_u32 ( ) )
19
+ }
20
+ }
21
+
19
22
#[ derive( Debug , Default ) ]
20
23
pub struct SerializedDepGraph {
21
- pub nodes : IndexVec < SerializedDepNodeIndex , SerializedNode > ,
24
+ pub ( super ) nodes : IndexVec < DepNodeIndex , DepNodeData > ,
25
+ pub ( super ) state : IndexVec < DepNodeIndex , DepNodeState > ,
22
26
}
23
27
24
- impl Decodable for SerializedDepGraph {
25
- fn decode < D : Decoder > ( d : & mut D ) -> Result < Self , D :: Error > {
28
+ impl SerializedDepGraph {
29
+ pub fn decode ( d : & mut opaque :: Decoder < ' _ > ) -> Result < Self , String > {
26
30
let mut nodes = IndexVec :: new ( ) ;
31
+ let mut invalidated_list = Vec :: new ( ) ;
27
32
loop {
28
- let count = d. read_usize ( ) ?;
29
- if count == 0 {
33
+ if d. position ( ) == d. data . len ( ) {
30
34
break ;
31
35
}
32
- for _ in 0 ..count {
33
- nodes. push ( SerializedNode :: decode ( d) ?) ;
36
+ match Action :: decode ( d) ? {
37
+ Action :: NewNodes ( new_nodes) => {
38
+ nodes. extend ( new_nodes) ;
39
+ }
40
+ Action :: UpdateNodes ( changed) => {
41
+ for ( i, data) in changed {
42
+ nodes[ i] = data;
43
+ }
44
+ }
45
+ Action :: InvalidateNodes ( nodes) => {
46
+ invalidated_list. extend ( nodes) ;
47
+ }
34
48
}
35
49
}
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
+ }
36
56
Ok ( SerializedDepGraph {
37
57
nodes,
58
+ state,
38
59
} )
39
60
}
40
61
}
41
62
42
- #[ derive( Debug , RustcDecodable ) ]
43
- pub struct SerializedNode {
44
- pub node : DepNode ,
45
- pub deps : Vec < SerializedDepNodeIndex > ,
46
- pub fingerprint : Fingerprint ,
63
+ #[ derive( Debug , RustcEncodable , RustcDecodable ) ]
64
+ enum Action {
65
+ NewNodes ( Vec < DepNodeData > ) ,
66
+ UpdateNodes ( Vec < ( DepNodeIndex , DepNodeData ) > ) ,
67
+ // FIXME: Is this redundant since these nodes will be also be updated?
68
+ // Could one of the indirect dependencies of a dep node change its result and
69
+ // cause a red node to be incorrectly green again?
70
+ // What about nodes which are in an unknown state?
71
+ // We must invalidate unknown nodes. Red nodes will have an entry in UpdateNodes
72
+ InvalidateNodes ( Vec < DepNodeIndex > )
47
73
}
48
74
49
75
struct SerializerWorker {
50
76
file : File ,
51
77
}
52
78
53
79
impl Worker for SerializerWorker {
54
- type Message = ( usize , Vec < DepNodeData > ) ;
80
+ type Message = ( usize , Action ) ;
55
81
type Result = ( ) ;
56
82
57
- fn message ( & mut self , ( buffer_size_est, nodes) : ( usize , Vec < DepNodeData > ) ) {
58
- let mut encoder = opaque:: Encoder :: new ( Vec :: with_capacity ( buffer_size_est * 4 ) ) ;
59
- assert ! ( !nodes. is_empty( ) ) ;
60
- encoder. emit_usize ( nodes. len ( ) ) . ok ( ) ;
61
- for data in nodes {
62
- data. node . encode ( & mut encoder) . ok ( ) ;
63
- data. edges . encode ( & mut encoder) . ok ( ) ;
64
- data. fingerprint . encode ( & mut encoder) . ok ( ) ;
65
- }
83
+ fn message ( & mut self , ( buffer_size_est, action) : ( usize , Action ) ) {
84
+ let mut encoder = opaque:: Encoder :: new ( Vec :: with_capacity ( buffer_size_est * 5 ) ) ;
85
+ action. encode ( & mut encoder) . ok ( ) ;
66
86
self . file . write_all ( & encoder. into_inner ( ) ) . expect ( "unable to write to temp dep graph" ) ;
67
87
}
68
88
69
- fn complete ( mut self ) {
70
- let mut encoder = opaque:: Encoder :: new ( Vec :: with_capacity ( 16 ) ) ;
71
- encoder. emit_usize ( 0 ) . ok ( ) ;
72
- self . file . write_all ( & encoder. into_inner ( ) ) . expect ( "unable to write to temp dep graph" ) ;
73
- }
89
+ fn complete ( self ) { }
74
90
}
75
91
76
92
const BUFFER_SIZE : usize = 800000 ;
77
93
78
94
pub struct Serializer {
79
95
worker : Lrc < WorkerExecutor < SerializerWorker > > ,
80
- buffer : Vec < DepNodeData > ,
81
- buffer_size : usize ,
96
+ new_buffer : Vec < DepNodeData > ,
97
+ new_buffer_size : usize ,
98
+ updated_buffer : Vec < ( DepNodeIndex , DepNodeData ) > ,
99
+ updated_buffer_size : usize ,
82
100
}
83
101
84
102
impl Serializer {
@@ -87,33 +105,65 @@ impl Serializer {
87
105
worker : Lrc :: new ( WorkerExecutor :: new ( SerializerWorker {
88
106
file,
89
107
} ) ) ,
90
- buffer : Vec :: with_capacity ( BUFFER_SIZE ) ,
91
- buffer_size : 0 ,
108
+ new_buffer : Vec :: with_capacity ( BUFFER_SIZE ) ,
109
+ new_buffer_size : 0 ,
110
+ updated_buffer : Vec :: with_capacity ( BUFFER_SIZE ) ,
111
+ updated_buffer_size : 0 ,
112
+ }
113
+ }
114
+
115
+ fn flush_new ( & mut self ) {
116
+ let msgs = mem:: replace ( & mut self . new_buffer , Vec :: with_capacity ( BUFFER_SIZE ) ) ;
117
+ let buffer_size = self . new_buffer_size ;
118
+ self . new_buffer_size = 0 ;
119
+ self . worker . message_in_pool ( ( buffer_size, Action :: NewNodes ( msgs) ) ) ;
120
+ }
121
+
122
+ #[ inline]
123
+ pub ( super ) fn serialize_new ( & mut self , data : DepNodeData ) {
124
+ let edges = data. edges . len ( ) ;
125
+ self . new_buffer . push ( data) ;
126
+ self . new_buffer_size += 8 + edges;
127
+ if unlikely ! ( self . new_buffer_size >= BUFFER_SIZE ) {
128
+ cold_path ( || {
129
+ self . flush_new ( ) ;
130
+ } )
92
131
}
93
132
}
94
133
95
- fn flush ( & mut self ) {
96
- let msgs = mem:: replace ( & mut self . buffer , Vec :: with_capacity ( BUFFER_SIZE ) ) ;
97
- let buffer_size = self . buffer_size ;
98
- self . buffer_size = 0 ;
99
- self . worker . message_in_pool ( ( buffer_size, msgs) ) ;
134
+ fn flush_updated ( & mut self ) {
135
+ let msgs = mem:: replace ( & mut self . updated_buffer , Vec :: with_capacity ( BUFFER_SIZE ) ) ;
136
+ let buffer_size = self . updated_buffer_size ;
137
+ self . updated_buffer_size = 0 ;
138
+ self . worker . message_in_pool ( ( buffer_size, Action :: UpdateNodes ( msgs) ) ) ;
100
139
}
101
140
102
141
#[ inline]
103
- pub ( super ) fn serialize ( & mut self , data : DepNodeData ) {
142
+ pub ( super ) fn serialize_updated ( & mut self , index : DepNodeIndex , data : DepNodeData ) {
104
143
let edges = data. edges . len ( ) ;
105
- self . buffer . push ( data) ;
106
- self . buffer_size += 8 + edges;
107
- if unlikely ! ( self . buffer_size >= BUFFER_SIZE ) {
144
+ self . updated_buffer . push ( ( index , data) ) ;
145
+ self . updated_buffer_size += 9 + edges;
146
+ if unlikely ! ( self . updated_buffer_size >= BUFFER_SIZE ) {
108
147
cold_path ( || {
109
- self . flush ( ) ;
148
+ self . flush_updated ( ) ;
110
149
} )
111
150
}
112
151
}
113
152
114
- pub fn complete ( & mut self ) {
115
- if self . buffer . len ( ) > 0 {
116
- self . flush ( ) ;
153
+ pub fn complete (
154
+ & mut self ,
155
+ invalidate : Vec < DepNodeIndex > ,
156
+ ) {
157
+ if self . new_buffer . len ( ) > 0 {
158
+ self . flush_new ( ) ;
159
+ }
160
+ if self . updated_buffer . len ( ) > 0 {
161
+ self . flush_updated ( ) ;
162
+ }
163
+ if !invalidate. is_empty ( ) {
164
+ self . worker . message_in_pool (
165
+ ( invalidate. len ( ) , Action :: InvalidateNodes ( invalidate) )
166
+ ) ;
117
167
}
118
168
self . worker . complete ( )
119
169
}
0 commit comments