r -> sexpr_car = x;
r -> sexpr_cdr = y;
GC_END_STUBBORN_CHANGE(r);
- return(r);
+ GC_reachable_here(x);
+ GC_reachable_here(y);
+ return r;
}
# endif
r -> sexpr_car = x;
r -> sexpr_cdr = y;
GC_END_STUBBORN_CHANGE(r);
- return(r);
+ GC_reachable_here(x);
+ GC_reachable_here(y);
+ return r;
}
#ifdef NO_CONS_ATOMIC_LEAF
r -> sexpr_car = x;
r -> sexpr_cdr = (sexpr)(~(GC_word)y);
GC_END_STUBBORN_CHANGE(r);
- return(r);
+ GC_reachable_here(x);
+ return r;
}
#ifdef GC_GCJ_SUPPORT
result -> sexpr_car = x;
result -> sexpr_cdr = y;
GC_END_STUBBORN_CHANGE(r);
- return(result);
+ 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);
- f[5] = ints(1,17);
+ tmp = ints(1,17);
+ f[5] = tmp;
+ GC_END_STUBBORN_CHANGE(f + 5);
+ GC_reachable_here(tmp);
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);
- g[799] = ints(1,18);
+ tmp = ints(1,18);
+ g[799] = tmp;
+ GC_END_STUBBORN_CHANGE(g + 799);
+ GC_reachable_here(tmp);
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
- h[1999] = gcj_ints(1,200);
- for (i = 0; i < 51; ++i)
- h[1999] = gcj_reverse(h[1999]);
+ tmp = gcj_ints(1,200);
+ h[1999] = tmp;
+ GC_END_STUBBORN_CHANGE(h + 1999);
+ GC_reachable_here(tmp);
+ for (i = 0; i < 51; ++i) {
+ tmp = gcj_reverse(h[1999]);
+ h[1999] = tmp;
+ GC_END_STUBBORN_CHANGE(h + 1999);
+ GC_reachable_here(tmp);
+ }
/* Leave it as the reversed list for now. */
# else
- h[1999] = ints(1,200);
+ tmp = ints(1,200);
+ h[1999] = tmp;
+ GC_END_STUBBORN_CHANGE(h + 1999);
+ GC_reachable_here(tmp);
# 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
- h[1999] = gcj_reverse(h[1999]);
+ tmp = gcj_reverse(h[1999]);
+ h[1999] = tmp;
+ GC_END_STUBBORN_CHANGE(h + 1999);
+ GC_reachable_here(tmp);
# endif
check_ints(h[1999], 1,200);
# ifndef THREADS
tn * mktree(int n)
{
tn * result = GC_NEW(tn);
+ tn * left, * right;
AO_fetch_and_add1(&collectable_count);
# if defined(MACOS)
if (n == 0) return(0);
CHECK_OUT_OF_MEMORY(result);
result -> level = n;
- result -> lchild = mktree(n-1);
- result -> rchild = mktree(n-1);
+ 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;
- tn * left = result -> lchild;
- tn * right = result -> rchild;
+ tn * tmp, * right_left;
CHECK_OUT_OF_MEMORY(left);
tmp = left -> rchild;
CHECK_OUT_OF_MEMORY(right);
- left -> rchild = right -> lchild;
+ 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);
}
if (AO_fetch_and_add1(&extra_count) % 119 == 0) {
# ifndef GC_NO_FINALIZATION
GC_reachable_here(result);
}
GC_END_STUBBORN_CHANGE(result);
+ GC_reachable_here(left);
+ GC_reachable_here(right);
return(result);
}
# else
void ** my_free_list_ptr;
void * my_free_list;
+ void * next;
my_free_list_ptr = (void **)pthread_getspecific(fl_key);
if (my_free_list_ptr == 0) {
my_free_list = GC_malloc_many(8);
CHECK_OUT_OF_MEMORY(my_free_list);
}
- *my_free_list_ptr = GC_NEXT(my_free_list);
+ next = GC_NEXT(my_free_list);
+ *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
}
dropped_something = 1;
FINALIZER_UNLOCK();
- GC_noop1((word)root); /* Root needs to remain live until */
+ GC_reachable_here(root); /* Root needs to remain live until */
/* dropped_something is set. */
root = mktree(TREE_HEIGHT);
chktree(root, TREE_HEIGHT);
newP[0] = 17;
newP[1] = (GC_word)old;
GC_END_STUBBORN_CHANGE(newP);
+ GC_reachable_here(old);
old = newP;
AO_fetch_and_add1(&collectable_count);
newP = (GC_word*)GC_malloc_explicitly_typed(33 * sizeof(GC_word), d3);
newP[0] = 17;
newP[1] = (GC_word)old;
GC_END_STUBBORN_CHANGE(newP);
+ GC_reachable_here(old);
old = newP;
AO_fetch_and_add1(&collectable_count);
newP = (GC_word *)GC_calloc_explicitly_typed(4, 2 * sizeof(GC_word),
newP[0] = 17;
newP[1] = (GC_word)old;
GC_END_STUBBORN_CHANGE(newP);
+ GC_reachable_here(old);
old = newP;
AO_fetch_and_add1(&collectable_count);
if (i & 0xff) {
newP[0] = 17;
newP[1] = (GC_word)old;
GC_END_STUBBORN_CHANGE(newP);
+ GC_reachable_here(old);
old = newP;
}
for (i = 0; i < 20000; i++) {
int B::deleting = 0;
+#define C_INIT_LEFT_RIGHT(arg_l, arg_r) \
+ { \
+ C *l = new C(arg_l); \
+ C *r = new C(arg_r); \
+ left = l; \
+ right = r; \
+ if (GC_is_heap_ptr(this)) { \
+ GC_END_STUBBORN_CHANGE(this); \
+ GC_reachable_here(l); \
+ GC_reachable_here(r); \
+ } \
+ }
class C: public GC_NS_QUALIFY(gc_cleanup), public A { public:
/* A collectible class with cleanup and virtual multiple inheritance. */
// a copy constructor and an assignment operator to workaround a cppcheck
// warning.
C(const C& c) : A(c.i), level(c.level), left(0), right(0) {
- if (level > 0) {
- left = new C(*c.left);
- right = new C(*c.right);
- GC_end_stubborn_change(left);
- GC_end_stubborn_change(right);
- }
+ if (level > 0)
+ C_INIT_LEFT_RIGHT(*c.left, *c.right);
}
C& operator=(const C& c) {
level = c.level;
left = 0;
right = 0;
- if (level > 0) {
- left = new C(*c.left);
- right = new C(*c.right);
- GC_end_stubborn_change(left);
- GC_end_stubborn_change(right);
- }
+ if (level > 0)
+ C_INIT_LEFT_RIGHT(*c.left, *c.right);
}
return *this;
}
GC_ATTR_EXPLICIT C( int levelArg ): A( levelArg ), level( levelArg ) {
nAllocated++;
if (level > 0) {
- left = new C( level - 1 );
- right = new C( level - 1 );
- GC_end_stubborn_change(left);
- GC_end_stubborn_change(right);
+ C_INIT_LEFT_RIGHT(level - 1, level - 1);
} else {
left = right = 0;}}
~C() {
exit(3);
}
*xptr = x;
- GC_end_stubborn_change(xptr);
+ GC_END_STUBBORN_CHANGE(xptr);
+ GC_reachable_here(x);
x = 0;
# endif
if (argc != 2
Later we'll check to make sure they've gone away. */
for (i = 0; i < 1000; i++) {
C* c = new C( 2 );
- GC_end_stubborn_change(c);
C c1( 2 ); /* stack allocation should work too */
D* d;
F* f;