Skip to content

Commit

Permalink
Add assertion in GC_set_fl_marks that there is no loop in freelist
Browse files Browse the repository at this point in the history
* alloc.c [GC_ASSERTIONS] (GC_set_fl_marks): Define q2 local variable;
call obj_link() twice for q2 on every loop iteration and assert that
q2!=q; add comment.
  • Loading branch information
ivmai committed Mar 3, 2024
1 parent 8697096 commit a85c6b1
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,9 @@ STATIC GC_bool GC_stopped_mark(GC_stop_func stop_func)
GC_INNER void GC_set_fl_marks(void **fl)
{
ptr_t q = (ptr_t)fl;
# ifdef GC_ASSERTIONS
ptr_t q2;
# endif
struct hblk *h = HBLKPTR(q);
struct hblk *last_h = h;
hdr *hhdr;
Expand All @@ -992,6 +995,9 @@ GC_INNER void GC_set_fl_marks(void **fl)
hhdr = HDR(h);
# ifdef MARK_BIT_PER_OBJ
sz = hhdr -> hb_sz;
# endif
# ifdef GC_ASSERTIONS
q2 = (ptr_t)obj_link(q);
# endif
for (;;) {
word bit_no = MARK_BIT_NO((ptr_t)q - (ptr_t)h, sz);
Expand All @@ -1002,6 +1008,20 @@ GC_INNER void GC_set_fl_marks(void **fl)
}
q = (ptr_t)obj_link(q);
if (NULL == q) break;
# ifdef GC_ASSERTIONS
/* Detect a cycle in the freelist. The algorithm is to */
/* have a second "twice faster" iterator over the list - */
/* the second iterator meets the first one in case of */
/* a cycle existing in the list. */
if (q2 != NULL) {
q2 = (ptr_t)obj_link(q2);
GC_ASSERT(q2 != q);
if (q2 != NULL) {
q2 = (ptr_t)obj_link(q2);
GC_ASSERT(q2 != q);
}
}
# endif

h = HBLKPTR(q);
if (EXPECT(h != last_h, FALSE)) {
Expand Down

0 comments on commit a85c6b1

Please sign in to comment.