result->left_len = (unsigned char)lenx;
result->len = (word)result_len;
result->left = x;
- result->right = y;
- GC_END_STUBBORN_CHANGE(result);
+ GC_PTR_STORE_AND_DIRTY(&result->right, y);
GC_reachable_here(x);
- GC_reachable_here(y);
if (depth >= MAX_DEPTH) {
return(CORD_balance((CORD)result));
} else {
result->left_len = (unsigned char)lenx;
result->len = (word)result_len;
result->left = x;
- result->right = y;
- GC_END_STUBBORN_CHANGE(result);
+ GC_PTR_STORE_AND_DIRTY(&result->right, y);
GC_reachable_here(x);
- GC_reachable_here(y);
if (depth >= MAX_DEPTH) {
return(CORD_balance((CORD)result));
} else {
/* depth is already 0 */
result->len = (word)len;
result->fn = fn;
- result->client_data = client_data;
- GC_END_STUBBORN_CHANGE(result);
- GC_reachable_here(client_data);
+ GC_PTR_STORE_AND_DIRTY(&result->client_data, client_data);
return (CordRep *)result;
}
}
CordRep * result;
if (sa == 0) OUT_OF_MEMORY;
- sa->sa_cord = (CordRep *)x;
sa->sa_index = i;
- GC_END_STUBBORN_CHANGE(sa);
- GC_reachable_here(x);
+ GC_PTR_STORE_AND_DIRTY(&sa->sa_cord, x);
result = CORD_from_fn_inner(f, (void *)sa, n);
if ((CORD)result != CORD_EMPTY && 0 == result -> function.null)
result -> function.header = SUBSTR_HDR;
# define GC_REGISTER_FINALIZER_UNREACHABLE(p, f, d, of, od) \
GC_debug_register_finalizer_unreachable(p, f, d, of, od)
# define GC_END_STUBBORN_CHANGE(p) GC_debug_end_stubborn_change(p)
+# define GC_PTR_STORE_AND_DIRTY(p, q) GC_debug_ptr_store_and_dirty(p, q)
# define GC_GENERAL_REGISTER_DISAPPEARING_LINK(link, obj) \
GC_general_register_disappearing_link(link, \
GC_base((/* no const */ void *)(obj)))
# define GC_REGISTER_FINALIZER_UNREACHABLE(p, f, d, of, od) \
GC_register_finalizer_unreachable(p, f, d, of, od)
# define GC_END_STUBBORN_CHANGE(p) GC_end_stubborn_change(p)
+# define GC_PTR_STORE_AND_DIRTY(p, q) GC_ptr_store_and_dirty(p, q)
# define GC_GENERAL_REGISTER_DISAPPEARING_LINK(link, obj) \
GC_general_register_disappearing_link(link, obj)
# define GC_REGISTER_LONG_LINK(link, obj) \
# define GC_PTR_STORE(p, q) (*(void **)(p) = (void *)(q))
#endif
+/* GC_PTR_STORE_AND_DIRTY(p,q) is equivalent to GC_PTR_STORE(p,q) */
+/* followed by GC_END_STUBBORN_CHANGE(p) and GC_reachable_here(q) */
+/* (assuming p and q do not have side effects). */
+GC_API void GC_CALL GC_ptr_store_and_dirty(void * /* p */,
+ const void * /* q */);
+GC_API void GC_CALL GC_debug_ptr_store_and_dirty(void * /* p */,
+ const void * /* q */);
+
/* Functions called to report pointer checking errors */
GC_API void (GC_CALLBACK * GC_same_obj_print_proc)(void * /* p */,
void * /* q */);
r = (sexpr)((char *)r + (my_extra & ~7));
# endif
r -> sexpr_car = x;
- r -> sexpr_cdr = y;
- GC_END_STUBBORN_CHANGE(r);
+ GC_PTR_STORE_AND_DIRTY(&r->sexpr_cdr, y);
GC_reachable_here(x);
- GC_reachable_here(y);
return r;
}
# endif
CHECK_OUT_OF_MEMORY(r);
AO_fetch_and_add1(&collectable_count);
r -> sexpr_car = x;
- r -> sexpr_cdr = y;
- GC_END_STUBBORN_CHANGE(r);
+ GC_PTR_STORE_AND_DIRTY(&r->sexpr_cdr, y);
GC_reachable_here(x);
- GC_reachable_here(y);
return r;
}
CHECK_OUT_OF_MEMORY(r);
AO_fetch_and_add1(&uncollectable_count);
- r -> sexpr_car = x;
r -> sexpr_cdr = (sexpr)(~(GC_word)y);
- GC_END_STUBBORN_CHANGE(r);
- GC_reachable_here(x);
+ GC_PTR_STORE_AND_DIRTY(&r->sexpr_car, x);
return r;
}
CHECK_OUT_OF_MEMORY(r);
result = (sexpr)(r + 1);
result -> sexpr_car = x;
- result -> sexpr_cdr = y;
- GC_END_STUBBORN_CHANGE(r);
+ GC_PTR_STORE_AND_DIRTY(&result->sexpr_cdr, y);
GC_reachable_here(x);
- GC_reachable_here(y);
return result;
}
#endif /* GC_GCJ_SUPPORT */
sexpr d;
sexpr e;
sexpr *f, *g, *h;
- sexpr tmp;
if (data == 0) {
/* This stack frame is not guaranteed to be scanned. */
f = (sexpr *)GC_REALLOC((void *)f, 6 * sizeof(sexpr));
CHECK_OUT_OF_MEMORY(f);
AO_fetch_and_add1(&realloc_count);
- tmp = ints(1,17);
- f[5] = tmp;
- GC_END_STUBBORN_CHANGE(f + 5);
- GC_reachable_here(tmp);
+ GC_PTR_STORE_AND_DIRTY(f + 5, ints(1, 17));
AO_fetch_and_add1(&collectable_count);
g = (sexpr *)GC_MALLOC(513 * sizeof(sexpr));
test_generic_malloc_or_special(g);
g = (sexpr *)GC_REALLOC((void *)g, 800 * sizeof(sexpr));
CHECK_OUT_OF_MEMORY(g);
AO_fetch_and_add1(&realloc_count);
- tmp = ints(1,18);
- g[799] = tmp;
- GC_END_STUBBORN_CHANGE(g + 799);
- GC_reachable_here(tmp);
+ GC_PTR_STORE_AND_DIRTY(g + 799, ints(1, 18));
AO_fetch_and_add1(&collectable_count);
h = (sexpr *)GC_MALLOC(1025 * sizeof(sexpr));
h = (sexpr *)GC_REALLOC((void *)h, 2000 * sizeof(sexpr));
CHECK_OUT_OF_MEMORY(h);
AO_fetch_and_add1(&realloc_count);
# ifdef GC_GCJ_SUPPORT
- tmp = gcj_ints(1,200);
- h[1999] = tmp;
- GC_END_STUBBORN_CHANGE(h + 1999);
- GC_reachable_here(tmp);
+ GC_PTR_STORE_AND_DIRTY(h + 1999, gcj_ints(1, 200));
for (i = 0; i < 51; ++i) {
- tmp = gcj_reverse(h[1999]);
- h[1999] = tmp;
- GC_END_STUBBORN_CHANGE(h + 1999);
- GC_reachable_here(tmp);
+ GC_PTR_STORE_AND_DIRTY(h + 1999, gcj_reverse(h[1999]));
}
/* Leave it as the reversed list for now. */
# else
- tmp = ints(1,200);
- h[1999] = tmp;
- GC_END_STUBBORN_CHANGE(h + 1999);
- GC_reachable_here(tmp);
+ GC_PTR_STORE_AND_DIRTY(h + 1999, ints(1, 200));
# endif
/* Try to force some collections and reuse of small list elements */
for (i = 0; i < 10; i++) {
check_ints(f[5], 1,17);
check_ints(g[799], 1,18);
# ifdef GC_GCJ_SUPPORT
- tmp = gcj_reverse(h[1999]);
- h[1999] = tmp;
- GC_END_STUBBORN_CHANGE(h + 1999);
- GC_reachable_here(tmp);
+ GC_PTR_STORE_AND_DIRTY(h + 1999, gcj_reverse(h[1999]));
# endif
check_ints(h[1999], 1,200);
# ifndef THREADS
result -> lchild = left = mktree(n - 1);
result -> rchild = right = mktree(n - 1);
if (AO_fetch_and_add1(&extra_count) % 17 == 0 && n >= 2) {
- tn * tmp, * right_left;
+ tn * tmp;
CHECK_OUT_OF_MEMORY(left);
tmp = left -> rchild;
CHECK_OUT_OF_MEMORY(right);
- right_left = right -> lchild;
- left -> rchild = right_left;
- right -> lchild = tmp;
- GC_END_STUBBORN_CHANGE(left);
- GC_reachable_here(right_left);
- GC_END_STUBBORN_CHANGE(right);
- GC_reachable_here(tmp);
+ GC_PTR_STORE_AND_DIRTY(&left->rchild, right->lchild);
+ GC_PTR_STORE_AND_DIRTY(&right->lchild, tmp);
}
if (AO_fetch_and_add1(&extra_count) % 119 == 0) {
# ifndef GC_NO_FINALIZATION
CHECK_OUT_OF_MEMORY(my_free_list);
}
next = GC_NEXT(my_free_list);
- *my_free_list_ptr = next;
+ GC_PTR_STORE_AND_DIRTY(my_free_list_ptr, next);
GC_NEXT(my_free_list) = 0;
- GC_END_STUBBORN_CHANGE(my_free_list_ptr);
- GC_reachable_here(next);
AO_fetch_and_add1(&collectable_count);
return(my_free_list);
# endif
newP = (GC_word *)GC_malloc_explicitly_typed(4 * sizeof(GC_word), d2);
CHECK_OUT_OF_MEMORY(newP);
newP[0] = 17;
- newP[1] = (GC_word)old;
- GC_END_STUBBORN_CHANGE(newP);
- GC_reachable_here(old);
+ GC_PTR_STORE_AND_DIRTY(newP + 1, old);
old = newP;
AO_fetch_and_add1(&collectable_count);
newP = (GC_word*)GC_malloc_explicitly_typed(33 * sizeof(GC_word), d3);
CHECK_OUT_OF_MEMORY(newP);
newP[0] = 17;
- newP[1] = (GC_word)old;
- GC_END_STUBBORN_CHANGE(newP);
- GC_reachable_here(old);
+ GC_PTR_STORE_AND_DIRTY(newP + 1, old);
old = newP;
AO_fetch_and_add1(&collectable_count);
newP = (GC_word *)GC_calloc_explicitly_typed(4, 2 * sizeof(GC_word),
d1);
CHECK_OUT_OF_MEMORY(newP);
newP[0] = 17;
- newP[1] = (GC_word)old;
- GC_END_STUBBORN_CHANGE(newP);
- GC_reachable_here(old);
+ GC_PTR_STORE_AND_DIRTY(newP + 1, old);
old = newP;
AO_fetch_and_add1(&collectable_count);
if (i & 0xff) {
}
CHECK_OUT_OF_MEMORY(newP);
newP[0] = 17;
- newP[1] = (GC_word)old;
- GC_END_STUBBORN_CHANGE(newP);
- GC_reachable_here(old);
+ GC_PTR_STORE_AND_DIRTY(newP + 1, old);
old = newP;
}
for (i = 0; i < 20000; i++) {