@@ -12,12 +12,15 @@ pub(crate) trait UnmarkPolicy {
12
12
fn invert_marker ( iter : & mut StacklessPreOrderHeapIter < Self > ) where Self : Sized ;
13
13
fn cycle_detected ( & mut self ) where Self : Sized ;
14
14
fn mark_phase ( & self ) -> bool ;
15
+ fn var_rooted_cycle ( _iter : & mut StacklessPreOrderHeapIter < Self > , _var_loc : usize , _next : usize )
16
+ where
17
+ Self : Sized { }
18
+ fn detect_list_tail_cycle ( _iter : & mut StacklessPreOrderHeapIter < Self > ) where Self : Sized { }
15
19
fn list_head_cycle_detecting_backward (
16
20
iter : & mut StacklessPreOrderHeapIter < Self > ,
17
21
) -> bool where Self : Sized {
18
22
iter. backward ( )
19
23
}
20
- fn detect_list_tail_cycle ( _iter : & mut StacklessPreOrderHeapIter < Self > ) where Self : Sized { }
21
24
}
22
25
23
26
pub ( crate ) struct IteratorUMP {
@@ -89,15 +92,21 @@ impl UnmarkPolicy for CycleDetectorUMP {
89
92
iter : & mut StacklessPreOrderHeapIter < Self > ,
90
93
) -> bool {
91
94
if !iter. iter_state . cycle_detected && iter. iter_state . mark_phase {
92
- iter. iter_state . cycle_detected = iter. detect_list_cycle ( ) ;
95
+ iter. iter_state . cycle_detected = iter. detect_list_cycle ( iter . current ) ;
93
96
}
94
97
95
98
iter. backward ( )
96
99
}
97
100
98
101
fn detect_list_tail_cycle ( iter : & mut StacklessPreOrderHeapIter < Self > ) {
99
102
if iter. iter_state . mark_phase && !iter. iter_state . cycle_detected {
100
- iter. iter_state . cycle_detected = iter. detect_list_cycle ( ) ;
103
+ iter. iter_state . cycle_detected = iter. detect_list_cycle ( iter. current ) ;
104
+ }
105
+ }
106
+
107
+ fn var_rooted_cycle ( iter : & mut StacklessPreOrderHeapIter < Self > , var_loc : usize , next : usize ) {
108
+ if var_loc != next && iter. iter_state . mark_phase && !iter. iter_state . cycle_detected {
109
+ iter. iter_state . cycle_detected = iter. detect_list_cycle ( next) ;
101
110
}
102
111
}
103
112
}
@@ -200,20 +209,20 @@ impl<'a> StacklessPreOrderHeapIter<'a, CycleDetectorUMP> {
200
209
self . iter_state . cycle_detected
201
210
}
202
211
203
- pub ( crate ) fn detect_list_cycle ( & self ) -> bool {
212
+ pub ( crate ) fn detect_list_cycle ( & self , next : usize ) -> bool {
204
213
use crate :: machine:: system_calls:: BrentAlgState ;
205
214
206
215
let mut brent_alg_st = BrentAlgState :: new ( self . current ) ;
207
216
208
217
while self . heap [ brent_alg_st. hare ] . get_mark_bit ( ) {
209
218
let temp = self . heap [ brent_alg_st. hare ] . get_value ( ) as usize ;
210
219
211
- if brent_alg_st. step ( temp) . is_some ( ) || temp == self . current {
220
+ if brent_alg_st. step ( temp) . is_some ( ) || temp == next {
212
221
return true ;
213
222
}
214
223
215
224
if temp == self . start {
216
- return self . heap [ temp ] . get_value ( ) == self . current as u64 ;
225
+ break ;
217
226
}
218
227
}
219
228
@@ -272,7 +281,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
272
281
#[ inline]
273
282
fn is_cyclic ( & self , var_current : usize , var_next : usize ) -> bool {
274
283
if self . heap [ var_next] . is_var ( ) {
275
- ! self . heap [ var_next] . get_forwarding_bit ( ) && var_current != var_next
284
+ self . heap [ var_next] . get_mark_bit ( ) && var_current != var_next
276
285
} else if self . heap [ var_next] . is_ref ( ) {
277
286
self . heap [ var_next] . get_mark_bit ( )
278
287
} else {
@@ -296,6 +305,8 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
296
305
}
297
306
298
307
return Some ( cell) ;
308
+ } else if self . heap [ next as usize ] . get_mark_bit ( ) == self . iter_state . mark_phase ( ) {
309
+ UMP :: var_rooted_cycle ( self , current, next as usize ) ;
299
310
}
300
311
301
312
if self . next < self . heap . len ( ) as u64 {
@@ -315,6 +326,8 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
315
326
}
316
327
317
328
return Some ( cell) ;
329
+ } else if self . heap [ next as usize ] . get_mark_bit ( ) == self . iter_state . mark_phase ( ) {
330
+ UMP :: var_rooted_cycle ( self , current, next as usize ) ;
318
331
}
319
332
320
333
if self . next < self . heap . len ( ) as u64 {
0 commit comments