ignore reads of tracked state when there is no current task
I realized that, even in the current system, such reads can't really do any harm. Because they are not part of a task, they will occur no matter what (only tasks can be skipped). If you leak the data you read into a task, that is bad, but that is equally bad if you are in a task. *Writes* to tracked state, on the other hand, should never occur except from within a task (and the task then records what things you read to compute it). Once we complete the shift to on-demand, these properties will hold by construction (because the on-demand struct enforces stateless tasks where leaks are impossible -- except by having shared mutable state in the tcx).
This commit is contained in:
parent
a3a5ff98eb
commit
69c9d9b3b8
@ -101,11 +101,15 @@ pub fn pop_task(&mut self, key: DepNode<D>) {
|
||||
}
|
||||
|
||||
/// Indicates that the current task `C` reads `v` by adding an
|
||||
/// edge from `v` to `C`. If there is no current task, panics. If
|
||||
/// you want to suppress this edge, use `ignore`.
|
||||
/// edge from `v` to `C`. If there is no current task, has no
|
||||
/// effect. Note that *reading* from tracked state is harmless if
|
||||
/// you are not in a task; what is bad is *writing* to tracked
|
||||
/// state (and leaking data that you read into a tracked task).
|
||||
pub fn read(&mut self, v: DepNode<D>) {
|
||||
let source = self.make_node(v);
|
||||
self.add_edge_from_current_node(|current| (source, current))
|
||||
if self.current_node().is_some() {
|
||||
let source = self.make_node(v);
|
||||
self.add_edge_from_current_node(|current| (source, current))
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates that the current task `C` writes `v` by adding an
|
||||
|
@ -80,7 +80,13 @@ pub fn enqueue(&self, message: &DepMessage) {
|
||||
|
||||
let mut stack = self.stack.borrow_mut();
|
||||
match *message {
|
||||
DepMessage::Read(ref n) => self.check_edge(Some(Some(n)), top(&stack)),
|
||||
// It is ok to READ shared state outside of a
|
||||
// task. That can't do any harm (at least, the only
|
||||
// way it can do harm is by leaking that data into a
|
||||
// query or task, which would be a problem
|
||||
// anyway). What would be bad is WRITING to that
|
||||
// state.
|
||||
DepMessage::Read(_) => { }
|
||||
DepMessage::Write(ref n) => self.check_edge(top(&stack), Some(Some(n))),
|
||||
DepMessage::PushTask(ref n) => stack.push(Some(n.clone())),
|
||||
DepMessage::PushIgnore => stack.push(None),
|
||||
@ -116,7 +122,7 @@ fn check_edge(&self,
|
||||
(None, None) => unreachable!(),
|
||||
|
||||
// nothing on top of the stack
|
||||
(None, Some(n)) | (Some(n), None) => bug!("read/write of {:?} but no current task", n),
|
||||
(None, Some(n)) | (Some(n), None) => bug!("write of {:?} but no current task", n),
|
||||
|
||||
// this corresponds to an Ignore being top of the stack
|
||||
(Some(None), _) | (_, Some(None)) => (),
|
||||
|
Loading…
Reference in New Issue
Block a user