about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-01-29 15:00:46 -0500
committerNiko Matsakis <niko@alum.mit.edu>2016-02-05 13:19:55 -0500
commit37fbfaf183a3c3f5fe2a9773927f2ceb92c4e247 (patch)
treef97ab0485133c47d9dc929b2629ad2bf57c795cc
parent98422e8c156d9cf343c93da30f71d9a4cabda25f (diff)
downloadrust-37fbfaf183a3c3f5fe2a9773927f2ceb92c4e247.tar.gz
rust-37fbfaf183a3c3f5fe2a9773927f2ceb92c4e247.zip
Add a local counter that tracks how many tasks are pushed or not pushed,
so that we can still get assertion failures even when dep-graph
construction is disabled.
-rw-r--r--src/librustc/dep_graph/thread.rs51
1 files changed, 47 insertions, 4 deletions
diff --git a/src/librustc/dep_graph/thread.rs b/src/librustc/dep_graph/thread.rs
index dbc57605d71..c43b4b15b76 100644
--- a/src/librustc/dep_graph/thread.rs
+++ b/src/librustc/dep_graph/thread.rs
@@ -19,6 +19,7 @@
 //! allocated (and both have a fairly large capacity).
 
 use rustc_data_structures::veccell::VecCell;
+use std::cell::Cell;
 use std::sync::mpsc::{self, Sender, Receiver};
 use std::thread;
 
@@ -39,6 +40,13 @@ pub enum DepMessage {
 pub struct DepGraphThreadData {
     enabled: bool,
 
+    // Local counter that just tracks how many tasks are pushed onto the
+    // stack, so that we still get an error in the case where one is
+    // missing. If dep-graph construction is enabled, we'd get the same
+    // error when processing tasks later on, but that's annoying because
+    // it lacks precision about the source of the error.
+    tasks_pushed: Cell<usize>,
+
     // current buffer, where we accumulate messages
     messages: VecCell<DepMessage>,
 
@@ -59,11 +67,14 @@ impl DepGraphThreadData {
         let (tx1, rx1) = mpsc::channel();
         let (tx2, rx2) = mpsc::channel();
         let (txq, rxq) = mpsc::channel();
+
         if enabled {
             thread::spawn(move || main(rx1, tx2, txq));
         }
+
         DepGraphThreadData {
             enabled: enabled,
+            tasks_pushed: Cell::new(0),
             messages: VecCell::with_capacity(INITIAL_CAPACITY),
             swap_in: rx2,
             swap_out: tx1,
@@ -71,6 +82,11 @@ impl DepGraphThreadData {
         }
     }
 
+    #[inline]
+    pub fn enabled(&self) -> bool {
+        self.enabled
+    }
+
     /// Sends the current batch of messages to the thread. Installs a
     /// new vector of messages.
     fn swap(&self) {
@@ -100,13 +116,40 @@ impl DepGraphThreadData {
     /// the buffer is full, this may swap.)
     #[inline]
     pub fn enqueue(&self, message: DepMessage) {
+        // Regardless of whether dep graph construction is enabled, we
+        // still want to check that we always have a valid task on the
+        // stack when a read/write/etc event occurs.
+        match message {
+            DepMessage::Read(_) | DepMessage::Write(_) =>
+                if self.tasks_pushed.get() == 0 {
+                    self.invalid_message("read/write but no current task")
+                },
+            DepMessage::PushTask(_) | DepMessage::PushIgnore =>
+                self.tasks_pushed.set(self.tasks_pushed.get() + 1),
+            DepMessage::PopTask(_) | DepMessage::PopIgnore =>
+                self.tasks_pushed.set(self.tasks_pushed.get() - 1),
+            DepMessage::Query =>
+                (),
+        }
+
         if self.enabled {
-            let len = self.messages.push(message);
-            if len == INITIAL_CAPACITY {
-                self.swap();
-            }
+            self.enqueue_enabled(message);
         }
     }
+
+    // Outline this fn since I expect it may want to be inlined
+    // separately.
+    fn enqueue_enabled(&self, message: DepMessage) {
+        let len = self.messages.push(message);
+        if len == INITIAL_CAPACITY {
+            self.swap();
+        }
+    }
+
+    // Outline this too.
+    fn invalid_message(&self, string: &str) {
+        panic!("{}; see src/librustc/dep_graph/README.md for more information", string)
+    }
 }
 
 /// Definition of the depgraph thread.