about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-28 18:44:34 +0000
committerGitHub <noreply@github.com>2020-04-28 18:44:34 +0000
commit9230ae5492bbfd73483d7f30918c1f686ebe46e9 (patch)
tree96d43a52891ef5d71dfbdb2812e25d7a1bf847c4
parentfdaa5e7ccffa04594c52c73234fed7615f378055 (diff)
parent24d18d92f69c1ce3d4fc3ff3be67d4f9bf65d857 (diff)
downloadrust-9230ae5492bbfd73483d7f30918c1f686ebe46e9.tar.gz
rust-9230ae5492bbfd73483d7f30918c1f686ebe46e9.zip
Merge #4148
4148: Simplify profiler impl (bubble up Option) r=matklad a=Veetaha



Co-authored-by: veetaha <veetaha2@gmail.com>
-rw-r--r--crates/ra_prof/src/hprof.rs45
1 files changed, 21 insertions, 24 deletions
diff --git a/crates/ra_prof/src/hprof.rs b/crates/ra_prof/src/hprof.rs
index 2b8a903636c..a3f5321fb3c 100644
--- a/crates/ra_prof/src/hprof.rs
+++ b/crates/ra_prof/src/hprof.rs
@@ -30,8 +30,9 @@ pub fn init_from(spec: &str) {
 pub type Label = &'static str;
 
 /// This function starts a profiling scope in the current execution stack with a given description.
-/// It returns a Profile structure and measure elapsed time between this method invocation and Profile structure drop.
-/// It supports nested profiling scopes in case when this function invoked multiple times at the execution stack. In this case the profiling information will be nested at the output.
+/// It returns a `Profile` struct that measures elapsed time between this method invocation and `Profile` struct drop.
+/// It supports nested profiling scopes in case when this function is invoked multiple times at the execution stack.
+/// In this case the profiling information will be nested at the output.
 /// Profiling information is being printed in the stderr.
 ///
 /// # Example
@@ -58,36 +59,35 @@ pub type Label = &'static str;
 /// ```
 pub fn profile(label: Label) -> Profiler {
     assert!(!label.is_empty());
-    let enabled = PROFILING_ENABLED.load(Ordering::Relaxed)
-        && PROFILE_STACK.with(|stack| stack.borrow_mut().push(label));
-    let label = if enabled { Some(label) } else { None };
-    Profiler { label, detail: None }
+
+    if PROFILING_ENABLED.load(Ordering::Relaxed)
+        && PROFILE_STACK.with(|stack| stack.borrow_mut().push(label))
+    {
+        Profiler(Some(ProfilerImpl { label, detail: None }))
+    } else {
+        Profiler(None)
+    }
 }
 
-pub struct Profiler {
-    label: Option<Label>,
+pub struct Profiler(Option<ProfilerImpl>);
+
+struct ProfilerImpl {
+    label: Label,
     detail: Option<String>,
 }
 
 impl Profiler {
     pub fn detail(mut self, detail: impl FnOnce() -> String) -> Profiler {
-        if self.label.is_some() {
-            self.detail = Some(detail())
+        if let Some(profiler) = &mut self.0 {
+            profiler.detail = Some(detail())
         }
         self
     }
 }
 
-impl Drop for Profiler {
+impl Drop for ProfilerImpl {
     fn drop(&mut self) {
-        match self {
-            Profiler { label: Some(label), detail } => {
-                PROFILE_STACK.with(|stack| {
-                    stack.borrow_mut().pop(label, detail.take());
-                });
-            }
-            Profiler { label: None, .. } => (),
-        }
+        PROFILE_STACK.with(|it| it.borrow_mut().pop(self.label, self.detail.take()));
     }
 }
 
@@ -179,21 +179,18 @@ impl ProfileStack {
     pub fn pop(&mut self, label: Label, detail: Option<String>) {
         let start = self.starts.pop().unwrap();
         let duration = start.elapsed();
-        let level = self.starts.len();
         self.messages.finish(Message { duration, label, detail });
-        if level == 0 {
+        if self.starts.is_empty() {
             let longer_than = self.filter.longer_than;
             // Convert to millis for comparison to avoid problems with rounding
             // (otherwise we could print `0ms` despite user's `>0` filter when
             // `duration` is just a few nanos).
             if duration.as_millis() > longer_than.as_millis() {
-                let stderr = stderr();
                 if let Some(root) = self.messages.root() {
-                    print(&self.messages, root, 0, longer_than, &mut stderr.lock());
+                    print(&self.messages, root, 0, longer_than, &mut stderr().lock());
                 }
             }
             self.messages.clear();
-            assert!(self.starts.is_empty())
         }
     }
 }