Move functions around.
In particular, it has bugged me for some time that `process_cycles` is currently located before `mark_still_waiting_nodes` despite being called afterwards.
This commit is contained in:
parent
a8207b1958
commit
7d550445e2
|
@ -520,6 +520,72 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a vector of obligations for `p` and all of its
|
||||||
|
/// ancestors, putting them into the error state in the process.
|
||||||
|
fn error_at(&self, mut index: usize) -> Vec<O> {
|
||||||
|
let mut error_stack: Vec<usize> = vec![];
|
||||||
|
let mut trace = vec![];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let node = &self.nodes[index];
|
||||||
|
node.state.set(NodeState::Error);
|
||||||
|
trace.push(node.obligation.clone());
|
||||||
|
if node.has_parent {
|
||||||
|
// The first dependent is the parent, which is treated
|
||||||
|
// specially.
|
||||||
|
error_stack.extend(node.dependents.iter().skip(1));
|
||||||
|
index = node.dependents[0];
|
||||||
|
} else {
|
||||||
|
// No parent; treat all dependents non-specially.
|
||||||
|
error_stack.extend(node.dependents.iter());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(index) = error_stack.pop() {
|
||||||
|
let node = &self.nodes[index];
|
||||||
|
if node.state.get() != NodeState::Error {
|
||||||
|
node.state.set(NodeState::Error);
|
||||||
|
error_stack.extend(node.dependents.iter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trace
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark all `Success` nodes that depend on a pending node as still
|
||||||
|
/// waiting. Upon completion, any `Success` nodes that aren't still waiting
|
||||||
|
/// can be removed by `compress`.
|
||||||
|
fn mark_still_waiting_nodes(&self) {
|
||||||
|
for node in &self.nodes {
|
||||||
|
if node.state.get() == NodeState::Pending {
|
||||||
|
// This call site is hot.
|
||||||
|
self.inlined_mark_dependents_as_still_waiting(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This always-inlined function is for the hot call site.
|
||||||
|
#[inline(always)]
|
||||||
|
fn inlined_mark_dependents_as_still_waiting(&self, node: &Node<O>) {
|
||||||
|
for &index in node.dependents.iter() {
|
||||||
|
let node = &self.nodes[index];
|
||||||
|
if let NodeState::Success(waiting) = node.state.get() {
|
||||||
|
if !self.is_still_waiting(waiting) {
|
||||||
|
node.state.set(NodeState::Success(self.still_waiting()));
|
||||||
|
// This call site is cold.
|
||||||
|
self.uninlined_mark_dependents_as_still_waiting(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This never-inlined function is for the cold call site.
|
||||||
|
#[inline(never)]
|
||||||
|
fn uninlined_mark_dependents_as_still_waiting(&self, node: &Node<O>) {
|
||||||
|
self.inlined_mark_dependents_as_still_waiting(node)
|
||||||
|
}
|
||||||
|
|
||||||
/// Report cycles between all `Success` nodes that aren't still waiting.
|
/// Report cycles between all `Success` nodes that aren't still waiting.
|
||||||
/// This must be called after `mark_still_waiting_nodes`.
|
/// This must be called after `mark_still_waiting_nodes`.
|
||||||
fn process_cycles<P>(&self, processor: &mut P)
|
fn process_cycles<P>(&self, processor: &mut P)
|
||||||
|
@ -571,72 +637,6 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a vector of obligations for `p` and all of its
|
|
||||||
/// ancestors, putting them into the error state in the process.
|
|
||||||
fn error_at(&self, mut index: usize) -> Vec<O> {
|
|
||||||
let mut error_stack: Vec<usize> = vec![];
|
|
||||||
let mut trace = vec![];
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let node = &self.nodes[index];
|
|
||||||
node.state.set(NodeState::Error);
|
|
||||||
trace.push(node.obligation.clone());
|
|
||||||
if node.has_parent {
|
|
||||||
// The first dependent is the parent, which is treated
|
|
||||||
// specially.
|
|
||||||
error_stack.extend(node.dependents.iter().skip(1));
|
|
||||||
index = node.dependents[0];
|
|
||||||
} else {
|
|
||||||
// No parent; treat all dependents non-specially.
|
|
||||||
error_stack.extend(node.dependents.iter());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while let Some(index) = error_stack.pop() {
|
|
||||||
let node = &self.nodes[index];
|
|
||||||
if node.state.get() != NodeState::Error {
|
|
||||||
node.state.set(NodeState::Error);
|
|
||||||
error_stack.extend(node.dependents.iter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trace
|
|
||||||
}
|
|
||||||
|
|
||||||
// This always-inlined function is for the hot call site.
|
|
||||||
#[inline(always)]
|
|
||||||
fn inlined_mark_dependents_as_still_waiting(&self, node: &Node<O>) {
|
|
||||||
for &index in node.dependents.iter() {
|
|
||||||
let node = &self.nodes[index];
|
|
||||||
if let NodeState::Success(waiting) = node.state.get() {
|
|
||||||
if !self.is_still_waiting(waiting) {
|
|
||||||
node.state.set(NodeState::Success(self.still_waiting()));
|
|
||||||
// This call site is cold.
|
|
||||||
self.uninlined_mark_dependents_as_still_waiting(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This never-inlined function is for the cold call site.
|
|
||||||
#[inline(never)]
|
|
||||||
fn uninlined_mark_dependents_as_still_waiting(&self, node: &Node<O>) {
|
|
||||||
self.inlined_mark_dependents_as_still_waiting(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mark all `Success` nodes that depend on a pending node as still
|
|
||||||
/// waiting. Upon completion, any `Success` nodes that aren't still waiting
|
|
||||||
/// can be removed by `compress`.
|
|
||||||
fn mark_still_waiting_nodes(&self) {
|
|
||||||
for node in &self.nodes {
|
|
||||||
if node.state.get() == NodeState::Pending {
|
|
||||||
// This call site is hot.
|
|
||||||
self.inlined_mark_dependents_as_still_waiting(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compresses the vector, removing all popped nodes. This adjusts the
|
/// Compresses the vector, removing all popped nodes. This adjusts the
|
||||||
/// indices and hence invalidates any outstanding indices. `process_cycles`
|
/// indices and hence invalidates any outstanding indices. `process_cycles`
|
||||||
/// must be run beforehand to remove any cycles on not-still-waiting
|
/// must be run beforehand to remove any cycles on not-still-waiting
|
||||||
|
|
Loading…
Reference in New Issue