Issue #471 - Ensure atomics are properly traced

This commit is contained in:
Justin Ethier 2021-07-28 22:39:18 -04:00
parent 14d4c27eac
commit 62b05528a2
2 changed files with 24 additions and 14 deletions

View file

@ -9,6 +9,7 @@ Features
Bug Fixes Bug Fixes
- When allocating a large vector we now guarantee all vector elements are initialized before the major collector can trace those elements. This avoids the potential for a race condition which could lead to a segmentation fault. - When allocating a large vector we now guarantee all vector elements are initialized before the major collector can trace those elements. This avoids the potential for a race condition which could lead to a segmentation fault.
- Ensure atomic objects are properly traced by the major garbage collector.
## 0.31.0 - July 27, 2021 ## 0.31.0 - July 27, 2021

37
gc.c
View file

@ -2263,6 +2263,7 @@ void gc_mark_black(object obj)
if (obj) { if (obj) {
gc_collector_mark_gray(obj, o); gc_collector_mark_gray(obj, o);
} }
break;
} }
default: default:
break; break;
@ -2281,46 +2282,54 @@ void gc_mark_black(object obj)
#else #else
// See full version above for debugging purposes. // See full version above for debugging purposes.
// Also sync any changes to this macro with the function version // Also sync any changes to this macro with the function version
#define gc_mark_black(obj) \ #define gc_mark_black(_obj) \
{ \ { \
int markColor = ck_pr_load_8(&gc_color_mark); \ int markColor = ck_pr_load_8(&gc_color_mark); \
if (is_object_type(obj) && mark(obj) != markColor) { \ if (is_object_type(_obj) && mark(_obj) != markColor) { \
switch (type_of(obj)) { \ switch (type_of(_obj)) { \
case pair_tag:{ \ case pair_tag:{ \
gc_collector_mark_gray(obj, car(obj)); \ gc_collector_mark_gray(_obj, car(_obj)); \
gc_collector_mark_gray(obj, cdr(obj)); \ gc_collector_mark_gray(_obj, cdr(_obj)); \
break; \ break; \
} \ } \
case closure1_tag: \ case closure1_tag: \
gc_collector_mark_gray(obj, ((closure1) obj)->element); \ gc_collector_mark_gray(_obj, ((closure1) _obj)->element); \
break; \ break; \
case closureN_tag:{ \ case closureN_tag:{ \
int i, n = ((closureN) obj)->num_elements; \ int i, n = ((closureN) _obj)->num_elements; \
for (i = 0; i < n; i++) { \ for (i = 0; i < n; i++) { \
gc_collector_mark_gray(obj, ((closureN) obj)->elements[i]); \ gc_collector_mark_gray(_obj, ((closureN) _obj)->elements[i]); \
} \ } \
break; \ break; \
} \ } \
case vector_tag:{ \ case vector_tag:{ \
int i, n = ((vector) obj)->num_elements; \ int i, n = ((vector) _obj)->num_elements; \
for (i = 0; i < n; i++) { \ for (i = 0; i < n; i++) { \
gc_collector_mark_gray(obj, ((vector) obj)->elements[i]); \ gc_collector_mark_gray(_obj, ((vector) _obj)->elements[i]); \
} \ } \
break; \ break; \
} \ } \
case cvar_tag:{ \ case cvar_tag:{ \
cvar_type *c = (cvar_type *) obj; \ cvar_type *c = (cvar_type *) _obj; \
object pvar = *(c->pvar); \ object pvar = *(c->pvar); \
if (pvar) { \ if (pvar) { \
gc_collector_mark_gray(obj, pvar); \ gc_collector_mark_gray(_obj, pvar); \
} \
break; \
} \
case atomic_tag: { \
atomic_type *a = (atomic_type *)_obj; \
object o = ck_pr_load_ptr(&(a->obj)); \
if (_obj) { \
gc_collector_mark_gray(_obj, o); \
} \ } \
break; \ break; \
} \ } \
default: \ default: \
break; \ break; \
} \ } \
if (mark(obj) != gc_color_red) { \ if (mark(_obj) != gc_color_red) { \
mark(obj) = markColor; \ mark(_obj) = markColor; \
} \ } \
} \ } \
} }