fix bugs & incompleteness of cycle-detecting stackless iterator (#2111)
This commit is contained in:
@@ -17,6 +17,7 @@ pub(crate) trait UnmarkPolicy {
|
|||||||
) -> bool where Self: Sized {
|
) -> bool where Self: Sized {
|
||||||
iter.backward()
|
iter.backward()
|
||||||
}
|
}
|
||||||
|
fn detect_list_tail_cycle(_iter: &mut StacklessPreOrderHeapIter<Self>) where Self: Sized {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct IteratorUMP {
|
pub(crate) struct IteratorUMP {
|
||||||
@@ -87,12 +88,18 @@ impl UnmarkPolicy for CycleDetectorUMP {
|
|||||||
fn list_head_cycle_detecting_backward(
|
fn list_head_cycle_detecting_backward(
|
||||||
iter: &mut StacklessPreOrderHeapIter<Self>,
|
iter: &mut StacklessPreOrderHeapIter<Self>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if !iter.iter_state.cycle_detected && iter.iter_state.mark_phase && iter.detect_list_cycle() {
|
if !iter.iter_state.cycle_detected && iter.iter_state.mark_phase {
|
||||||
iter.iter_state.cycle_detected = true;
|
iter.iter_state.cycle_detected = iter.detect_list_cycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
iter.backward()
|
iter.backward()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn detect_list_tail_cycle(iter: &mut StacklessPreOrderHeapIter<Self>) {
|
||||||
|
if iter.iter_state.mark_phase && !iter.iter_state.cycle_detected {
|
||||||
|
iter.iter_state.cycle_detected = iter.detect_list_cycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MarkerUMP {}
|
struct MarkerUMP {}
|
||||||
@@ -273,7 +280,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
let current = self.current;
|
let current = self.current;
|
||||||
|
|
||||||
if let Some(cell) = UMP::forward_attr_var(self) {
|
if let Some(cell) = UMP::forward_attr_var(self) {
|
||||||
if current as u64 != next && self.heap[next as usize].is_ref() {
|
if current as u64 != next && self.heap[next as usize].is_compound(self.heap) {
|
||||||
self.iter_state.cycle_detected();
|
self.iter_state.cycle_detected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +299,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
let current = self.current;
|
let current = self.current;
|
||||||
|
|
||||||
if let Some(cell) = self.forward_var() {
|
if let Some(cell) = self.forward_var() {
|
||||||
if current as u64 != next && self.heap[next as usize].is_ref() {
|
if current as u64 != next && self.heap[next as usize].is_compound(self.heap) {
|
||||||
self.iter_state.cycle_detected();
|
self.iter_state.cycle_detected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,6 +354,11 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
if self.heap[last_cell_loc-1].get_mark_bit() == self.iter_state.mark_phase() {
|
if self.heap[last_cell_loc-1].get_mark_bit() == self.iter_state.mark_phase() {
|
||||||
// the conjunction leading here is a necessary but not sufficient
|
// the conjunction leading here is a necessary but not sufficient
|
||||||
// condition of the presence of a cycle at the list head.
|
// condition of the presence of a cycle at the list head.
|
||||||
|
|
||||||
|
if last_cell_loc == self.current {
|
||||||
|
UMP::detect_list_tail_cycle(self);
|
||||||
|
}
|
||||||
|
|
||||||
self.backward();
|
self.backward();
|
||||||
|
|
||||||
if UMP::list_head_cycle_detecting_backward(self) {
|
if UMP::list_head_cycle_detecting_backward(self) {
|
||||||
|
|||||||
Reference in New Issue
Block a user