@@ -97,6 +97,7 @@ use std::time::{Duration, Instant};
9797pub  use  measureme:: EventId ; 
9898use  measureme:: { EventIdBuilder ,  Profiler ,  SerializableString ,  StringId } ; 
9999use  parking_lot:: RwLock ; 
100+ use  serde_json:: json; 
100101use  smallvec:: SmallVec ; 
101102
102103bitflags:: bitflags! { 
@@ -145,6 +146,15 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
145146/// Something that uniquely identifies a query invocation. 
146147pub  struct  QueryInvocationId ( pub  u32 ) ; 
147148
149+ /// Which format to use for `-Z time-passes` 
150+ #[ derive( Clone ,  Copy ,  PartialEq ,  Hash ,  Debug ) ]  
151+ pub  enum  TimePassesFormat  { 
152+     /// Emit human readable text 
153+      Text , 
154+     /// Emit structured JSON 
155+      Json , 
156+ } 
157+ 
148158/// A reference to the SelfProfiler. It can be cloned and sent across thread 
149159/// boundaries at will. 
150160#[ derive( Clone ) ]  
@@ -158,14 +168,14 @@ pub struct SelfProfilerRef {
158168    // actually enabled. 
159169    event_filter_mask :  EventFilter , 
160170
161-     // Print verbose generic activities to stderr?  
162-     print_verbose_generic_activities :  bool , 
171+     // Print verbose generic activities to stderr.  
172+     print_verbose_generic_activities :  Option < TimePassesFormat > , 
163173} 
164174
165175impl  SelfProfilerRef  { 
166176    pub  fn  new ( 
167177        profiler :  Option < Arc < SelfProfiler > > , 
168-         print_verbose_generic_activities :  bool , 
178+         print_verbose_generic_activities :  Option < TimePassesFormat > , 
169179    )  -> SelfProfilerRef  { 
170180        // If there is no SelfProfiler then the filter mask is set to NONE, 
171181        // ensuring that nothing ever tries to actually access it. 
@@ -207,9 +217,10 @@ impl SelfProfilerRef {
207217     /// a measureme event, "verbose" generic activities also print a timing entry to 
208218     /// stderr if the compiler is invoked with -Ztime-passes. 
209219     pub  fn  verbose_generic_activity ( & self ,  event_label :  & ' static  str )  -> VerboseTimingGuard < ' _ >  { 
210-         let  message = self . print_verbose_generic_activities . then ( || event_label. to_owned ( ) ) ; 
220+         let  message_and_format =
221+             self . print_verbose_generic_activities . map ( |format| ( event_label. to_owned ( ) ,  format) ) ; 
211222
212-         VerboseTimingGuard :: start ( message ,  self . generic_activity ( event_label) ) 
223+         VerboseTimingGuard :: start ( message_and_format ,  self . generic_activity ( event_label) ) 
213224    } 
214225
215226    /// Like `verbose_generic_activity`, but with an extra arg. 
@@ -221,11 +232,14 @@ impl SelfProfilerRef {
221232    where 
222233        A :  Borrow < str >  + Into < String > , 
223234    { 
224-         let  message  = self 
235+         let  message_and_format  = self 
225236            . print_verbose_generic_activities 
226-             . then ( ||  format ! ( "{}({})" ,  event_label,  event_arg. borrow( ) ) ) ; 
237+             . map ( |format|  ( format ! ( "{}({})" ,  event_label,  event_arg. borrow( ) ) ,  format ) ) ; 
227238
228-         VerboseTimingGuard :: start ( message,  self . generic_activity_with_arg ( event_label,  event_arg) ) 
239+         VerboseTimingGuard :: start ( 
240+             message_and_format, 
241+             self . generic_activity_with_arg ( event_label,  event_arg) , 
242+         ) 
229243    } 
230244
231245    /// Start profiling a generic activity. Profiling continues until the 
@@ -703,17 +717,32 @@ impl<'a> TimingGuard<'a> {
703717    } 
704718} 
705719
720+ struct  VerboseInfo  { 
721+     start_time :  Instant , 
722+     start_rss :  Option < usize > , 
723+     message :  String , 
724+     format :  TimePassesFormat , 
725+ } 
726+ 
706727#[ must_use]  
707728pub  struct  VerboseTimingGuard < ' a >  { 
708-     start_and_message :  Option < ( Instant ,   Option < usize > ,   String ) > , 
729+     info :  Option < VerboseInfo > , 
709730    _guard :  TimingGuard < ' a > , 
710731} 
711732
712733impl < ' a >  VerboseTimingGuard < ' a >  { 
713-     pub  fn  start ( message :  Option < String > ,  _guard :  TimingGuard < ' a > )  -> Self  { 
734+     pub  fn  start ( 
735+         message_and_format :  Option < ( String ,  TimePassesFormat ) > , 
736+         _guard :  TimingGuard < ' a > , 
737+     )  -> Self  { 
714738        VerboseTimingGuard  { 
715739            _guard, 
716-             start_and_message :  message. map ( |msg| ( Instant :: now ( ) ,  get_resident_set_size ( ) ,  msg) ) , 
740+             info :  message_and_format. map ( |( message,  format) | VerboseInfo  { 
741+                 start_time :  Instant :: now ( ) , 
742+                 start_rss :  get_resident_set_size ( ) , 
743+                 message, 
744+                 format, 
745+             } ) , 
717746        } 
718747    } 
719748
@@ -726,10 +755,10 @@ impl<'a> VerboseTimingGuard<'a> {
726755
727756impl  Drop  for  VerboseTimingGuard < ' _ >  { 
728757    fn  drop ( & mut  self )  { 
729-         if  let  Some ( ( start_time ,  start_rss ,   ref  message ) )  = self . start_and_message  { 
758+         if  let  Some ( info )  = & self . info  { 
730759            let  end_rss = get_resident_set_size ( ) ; 
731-             let  dur = start_time. elapsed ( ) ; 
732-             print_time_passes_entry ( message,  dur,  start_rss,  end_rss) ; 
760+             let  dur = info . start_time . elapsed ( ) ; 
761+             print_time_passes_entry ( & info . message ,  dur,  info . start_rss ,  end_rss,  info . format ) ; 
733762        } 
734763    } 
735764} 
@@ -739,7 +768,22 @@ pub fn print_time_passes_entry(
739768    dur :  Duration , 
740769    start_rss :  Option < usize > , 
741770    end_rss :  Option < usize > , 
771+     format :  TimePassesFormat , 
742772)  { 
773+     match  format { 
774+         TimePassesFormat :: Json  => { 
775+             let  json = json ! ( { 
776+                 "pass" :  what, 
777+                 "time" :  dur. as_secs_f64( ) , 
778+                 "rss_start" :  start_rss, 
779+                 "rss_end" :  end_rss, 
780+             } ) ; 
781+             eprintln ! ( "time: {}" ,  json. to_string( ) ) ; 
782+             return ; 
783+         } 
784+         TimePassesFormat :: Text  => ( ) , 
785+     } 
786+ 
743787    // Print the pass if its duration is greater than 5 ms, or it changed the 
744788    // measured RSS. 
745789    let  is_notable = || { 
0 commit comments