Skip to content

Commit 37fbfaf

Browse files
committed
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.
1 parent 98422e8 commit 37fbfaf

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

src/librustc/dep_graph/thread.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
//! allocated (and both have a fairly large capacity).
2020
2121
use rustc_data_structures::veccell::VecCell;
22+
use std::cell::Cell;
2223
use std::sync::mpsc::{self, Sender, Receiver};
2324
use std::thread;
2425

@@ -39,6 +40,13 @@ pub enum DepMessage {
3940
pub struct DepGraphThreadData {
4041
enabled: bool,
4142

43+
// Local counter that just tracks how many tasks are pushed onto the
44+
// stack, so that we still get an error in the case where one is
45+
// missing. If dep-graph construction is enabled, we'd get the same
46+
// error when processing tasks later on, but that's annoying because
47+
// it lacks precision about the source of the error.
48+
tasks_pushed: Cell<usize>,
49+
4250
// current buffer, where we accumulate messages
4351
messages: VecCell<DepMessage>,
4452

@@ -59,18 +67,26 @@ impl DepGraphThreadData {
5967
let (tx1, rx1) = mpsc::channel();
6068
let (tx2, rx2) = mpsc::channel();
6169
let (txq, rxq) = mpsc::channel();
70+
6271
if enabled {
6372
thread::spawn(move || main(rx1, tx2, txq));
6473
}
74+
6575
DepGraphThreadData {
6676
enabled: enabled,
77+
tasks_pushed: Cell::new(0),
6778
messages: VecCell::with_capacity(INITIAL_CAPACITY),
6879
swap_in: rx2,
6980
swap_out: tx1,
7081
query_in: rxq,
7182
}
7283
}
7384

85+
#[inline]
86+
pub fn enabled(&self) -> bool {
87+
self.enabled
88+
}
89+
7490
/// Sends the current batch of messages to the thread. Installs a
7591
/// new vector of messages.
7692
fn swap(&self) {
@@ -100,13 +116,40 @@ impl DepGraphThreadData {
100116
/// the buffer is full, this may swap.)
101117
#[inline]
102118
pub fn enqueue(&self, message: DepMessage) {
119+
// Regardless of whether dep graph construction is enabled, we
120+
// still want to check that we always have a valid task on the
121+
// stack when a read/write/etc event occurs.
122+
match message {
123+
DepMessage::Read(_) | DepMessage::Write(_) =>
124+
if self.tasks_pushed.get() == 0 {
125+
self.invalid_message("read/write but no current task")
126+
},
127+
DepMessage::PushTask(_) | DepMessage::PushIgnore =>
128+
self.tasks_pushed.set(self.tasks_pushed.get() + 1),
129+
DepMessage::PopTask(_) | DepMessage::PopIgnore =>
130+
self.tasks_pushed.set(self.tasks_pushed.get() - 1),
131+
DepMessage::Query =>
132+
(),
133+
}
134+
103135
if self.enabled {
104-
let len = self.messages.push(message);
105-
if len == INITIAL_CAPACITY {
106-
self.swap();
107-
}
136+
self.enqueue_enabled(message);
108137
}
109138
}
139+
140+
// Outline this fn since I expect it may want to be inlined
141+
// separately.
142+
fn enqueue_enabled(&self, message: DepMessage) {
143+
let len = self.messages.push(message);
144+
if len == INITIAL_CAPACITY {
145+
self.swap();
146+
}
147+
}
148+
149+
// Outline this too.
150+
fn invalid_message(&self, string: &str) {
151+
panic!("{}; see src/librustc/dep_graph/README.md for more information", string)
152+
}
110153
}
111154

112155
/// Definition of the depgraph thread.

0 commit comments

Comments
 (0)