88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11+ use std:: time:: { Instant } ;
1112use rustc:: util:: common:: { ProfQDumpParams , ProfileQueriesMsg , profq_msg, profq_set_chan} ;
1213use std:: sync:: mpsc:: { Receiver } ;
1314use std:: io:: { Write } ;
@@ -41,14 +42,30 @@ pub fn dump(path:String) {
4142 let _ = rx. recv ( ) . unwrap ( ) ;
4243}
4344
45+ // State for parsing recursive trace structure in separate thread, via messages
46+ #[ derive( Clone , Eq , PartialEq ) ]
47+ enum ParseState {
48+ // No (local) parse state; may be parsing a tree, focused on a
49+ // sub-tree that could be anything.
50+ Clear ,
51+ // Have Query information from the last message
52+ HaveQuery ( trace:: Query , Instant ) ,
53+ // Have "time-begin" information from the last message (doit flag, and message)
54+ HaveTimeBegin ( String , Instant ) ,
55+ }
56+ struct StackFrame {
57+ pub parse_st : ParseState ,
58+ pub traces : Vec < trace:: Rec > ,
59+ }
60+
4461// profiling thread; retains state (in local variables) and dump traces, upon request.
4562fn profile_queries_thread ( r : Receiver < ProfileQueriesMsg > ) {
4663 use self :: trace:: * ;
4764 use std:: fs:: File ;
4865 use std:: time:: { Instant } ;
4966
5067 let mut profq_msgs : Vec < ProfileQueriesMsg > = vec ! [ ] ;
51- let mut frame : StackFrame = StackFrame { parse_st : ParseState :: NoQuery , traces : vec ! [ ] } ;
68+ let mut frame : StackFrame = StackFrame { parse_st : ParseState :: Clear , traces : vec ! [ ] } ;
5269 let mut stack : Vec < StackFrame > = vec ! [ ] ;
5370 loop {
5471 let msg = r. recv ( ) ;
@@ -64,7 +81,7 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
6481 ProfileQueriesMsg :: Halt => return ,
6582 ProfileQueriesMsg :: Dump ( params) => {
6683 assert ! ( stack. len( ) == 0 ) ;
67- assert ! ( frame. parse_st == trace :: ParseState :: NoQuery ) ;
84+ assert ! ( frame. parse_st == ParseState :: Clear ) ;
6885 {
6986 // write log of all messages
7087 if params. dump_profq_msg_log {
@@ -94,6 +111,10 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
94111 trace:: write_traces ( & mut html_file, & mut counts_file, & frame. traces ) ;
95112 write ! ( html_file, "</body>\n </html>\n " ) . unwrap ( ) ;
96113
114+ let ack_path = format ! ( "{}.ack" , params. path) ;
115+ let ack_file = File :: create ( & ack_path) . unwrap ( ) ;
116+ drop ( ack_file) ;
117+
97118 // Tell main thread that we are done, e.g., so it can exit
98119 params. ack . send ( ( ) ) . unwrap ( ) ;
99120 }
@@ -108,35 +129,33 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
108129 ( _, ProfileQueriesMsg :: Halt ) => unreachable ! ( ) ,
109130 ( _, ProfileQueriesMsg :: Dump ( _) ) => unreachable ! ( ) ,
110131
111- // Parse State: NoQuery
112- ( ParseState :: NoQuery ,
132+ // Parse State: Clear
133+ ( ParseState :: Clear ,
113134 ProfileQueriesMsg :: QueryBegin ( span, querymsg) ) => {
114135 let start = Instant :: now ( ) ;
115136 frame. parse_st = ParseState :: HaveQuery
116137 ( Query { span : span, msg : querymsg} , start)
117138 } ,
118- ( ParseState :: NoQuery ,
139+ ( ParseState :: Clear ,
119140 ProfileQueriesMsg :: CacheHit ) => {
120141 panic ! ( "parse error: unexpected CacheHit; expected QueryBegin" )
121142 } ,
122- ( ParseState :: NoQuery ,
143+ ( ParseState :: Clear ,
123144 ProfileQueriesMsg :: ProviderBegin ) => {
124145 panic ! ( "parse error: expected QueryBegin before beginning a provider" )
125146 } ,
126- ( ParseState :: NoQuery ,
147+ ( ParseState :: Clear ,
127148 ProfileQueriesMsg :: ProviderEnd ) => {
128149 let provider_extent = frame. traces ;
129150 match stack. pop ( ) {
130151 None =>
131152 panic ! ( "parse error: expected a stack frame; found an empty stack" ) ,
132153 Some ( old_frame) => {
133154 match old_frame. parse_st {
134- ParseState :: NoQuery =>
135- panic ! ( "parse error: expected a stack frame for a query" ) ,
136- ParseState :: HaveQuery ( q, start) => {
155+ ParseState :: HaveQuery ( q, start) => {
137156 let duration = start. elapsed ( ) ;
138157 frame = StackFrame {
139- parse_st : ParseState :: NoQuery ,
158+ parse_st : ParseState :: Clear ,
140159 traces : old_frame. traces
141160 } ;
142161 let trace = Rec {
@@ -146,11 +165,66 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
146165 duration : duration,
147166 } ;
148167 frame. traces . push ( trace ) ;
149- }
168+ } ,
169+ _ => panic ! ( "internal parse error: malformed parse stack" )
150170 }
151171 }
152172 }
153- }
173+ } ,
174+
175+
176+ ( ParseState :: Clear ,
177+ ProfileQueriesMsg :: TimeBegin ( msg) ) => {
178+ let start = Instant :: now ( ) ;
179+ frame. parse_st = ParseState :: HaveTimeBegin ( msg, start) ;
180+ stack. push ( frame) ;
181+ frame = StackFrame { parse_st : ParseState :: Clear , traces : vec ! [ ] } ;
182+ } ,
183+ ( _, ProfileQueriesMsg :: TimeBegin ( _) ) =>
184+ panic ! ( "parse error; did not expect time begin here" ) ,
185+
186+ ( ParseState :: Clear ,
187+ ProfileQueriesMsg :: TimeEnd ) => {
188+ let provider_extent = frame. traces ;
189+ match stack. pop ( ) {
190+ None =>
191+ panic ! ( "parse error: expected a stack frame; found an empty stack" ) ,
192+ Some ( old_frame) => {
193+ match old_frame. parse_st {
194+ ParseState :: HaveTimeBegin ( msg, start) => {
195+ let duration = start. elapsed ( ) ;
196+ frame = StackFrame {
197+ parse_st : ParseState :: Clear ,
198+ traces : old_frame. traces
199+ } ;
200+ let trace = Rec {
201+ effect : Effect :: TimeBegin ( msg) ,
202+ extent : Box :: new ( provider_extent) ,
203+ start : start,
204+ duration : duration,
205+ } ;
206+ frame. traces . push ( trace ) ;
207+ } ,
208+ _ => panic ! ( "internal parse error: malformed parse stack" )
209+ }
210+ }
211+ }
212+ } ,
213+ ( _, ProfileQueriesMsg :: TimeEnd ) => { panic ! ( "parse error" ) }
214+
215+
216+ // Parse State: HaveTimeBegin -- for timing old
217+ // passes in driver (outside of query model, but
218+ // still in use)
219+ ( ParseState :: HaveTimeBegin ( _, _) ,
220+ ProfileQueriesMsg :: ProviderBegin ) => {
221+ } ,
222+ ( ParseState :: HaveTimeBegin ( _, _) ,
223+ ProfileQueriesMsg :: CacheHit ) => { unreachable ! ( ) } ,
224+ ( ParseState :: HaveTimeBegin ( _, _) ,
225+ ProfileQueriesMsg :: QueryBegin ( _, _) ) => { unreachable ! ( ) } ,
226+ ( ParseState :: HaveTimeBegin ( _, _) ,
227+ ProfileQueriesMsg :: ProviderEnd ) => { unreachable ! ( ) } ,
154228
155229 // Parse State: HaveQuery
156230 ( ParseState :: HaveQuery ( q, start) ,
@@ -163,12 +237,12 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
163237 duration : duration,
164238 } ;
165239 frame. traces . push ( trace ) ;
166- frame. parse_st = ParseState :: NoQuery ;
240+ frame. parse_st = ParseState :: Clear ;
167241 } ,
168242 ( ParseState :: HaveQuery ( _, _) ,
169243 ProfileQueriesMsg :: ProviderBegin ) => {
170244 stack. push ( frame) ;
171- frame = StackFrame { parse_st : ParseState :: NoQuery , traces : vec ! [ ] } ;
245+ frame = StackFrame { parse_st : ParseState :: Clear , traces : vec ! [ ] } ;
172246 } ,
173247 ( ParseState :: HaveQuery ( q, _) ,
174248 ProfileQueriesMsg :: ProviderEnd ) => {
0 commit comments