2005-04-14
2005-04-14 16:48:00 by Martin Stjernholm <mast@lysator.liu.se>
-
1bad5c25033fb2156415a7242d5f497857a01e7f
(417 lines)
(+249/-168)
[
Show
| Annotate
]
Branch: 7.9
Refactored the gc frame structs a bit to improve typing and to make it
possible to change the block_alloc storage.
Rev: src/gc.c:1.266
Rev: src/gc.h:1.119
2:
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: gc.c,v 1.265 2005/04/09 10:52:52 grubba Exp $
+ || $Id: gc.c,v 1.266 2005/04/14 16:48:00 mast Exp $
*/
#include "global.h"
110:
int gc_destruct_everything = 0;
#endif
- struct gc_frame
+ /* Shared fields between link and pop frames. */
+ #define GC_STACK_COMMON_FIELDS \
+ void *data; \
+ struct gc_stack_frame *s_prev; /* Previous stack frame. */ \
+ unsigned INT16 frameflags
+
+ struct gc_stack_frame
{
- struct gc_frame *back; /* Previous stack frame. */
+ GC_STACK_COMMON_FIELDS;
+ };
+
+ struct gc_link_frame
+ {
+ GC_STACK_COMMON_FIELDS;
+ INT16 weak; /* Weak flag to checkfn. */
+ gc_cycle_check_cb *checkfn;
+ };
+
+ struct gc_pop_frame
+ {
+ GC_STACK_COMMON_FIELDS;
+ unsigned INT16 cycle; /* Cycle id number. */
+ struct gc_pop_frame *prev; /* Previous frame in rec_list. */
+ struct gc_pop_frame *next; /* Next pointer in rec_list and kill_list. */
+ };
+
+ struct gc_free_extra_frame /* Used on free_extra_list. See gc_delayed_free. */
+ {
void *data;
-
+ struct gc_free_extra_frame *fe_next; /* Next pointer. */
+ int type; /* The type of the thing. */
+ };
+
+ struct gc_frame
+ {
union {
- struct { /* Pop frame. */
- struct gc_frame *prev; /* Previous frame in rec_list. */
- struct gc_frame *next; /* Next pointer in rec_list and kill_list. */
- unsigned INT16 cycle; /* Cycle id number. */
- } pop;
- struct { /* Link frame. */
- gc_cycle_check_cb *checkfn;
- int weak;
- } link;
- int free_extra_type; /* Used on free_extra_list. The type of the thing. */
+ struct gc_link_frame link;
+ struct gc_pop_frame pop;
+ struct gc_free_extra_frame free_extra;
+ struct gc_frame *next; /* For block_alloc. */
} u;
- unsigned INT16 frameflags;
+
};
-
+ /* frameflags bits. */
#define GC_POP_FRAME 0x01
#define GC_WEAK_REF 0x02
#define GC_STRONG_REF 0x04
140:
#endif
#undef BLOCK_ALLOC_NEXT
- #define BLOCK_ALLOC_NEXT back
+ #define BLOCK_ALLOC_NEXT u.next
BLOCK_ALLOC(gc_frame,GC_LINK_CHUNK_SIZE)
- #define PREV(frame) ((frame)->u.pop.prev)
- #define NEXT(frame) ((frame)->u.pop.next)
- #define CYCLE(frame) ((frame)->u.pop.cycle)
+ static INLINE struct gc_pop_frame *alloc_pop_frame()
+ {
+ struct gc_frame *f = alloc_gc_frame();
+ f->u.pop.frameflags = GC_POP_FRAME;
+ return (struct gc_pop_frame *) f;
+ }
-
+ static INLINE struct gc_link_frame *alloc_link_frame()
+ {
+ struct gc_frame *f = alloc_gc_frame();
+ f->u.link.frameflags = 0;
+ return (struct gc_link_frame *) f;
+ }
+
+ static INLINE struct gc_free_extra_frame *alloc_free_extra_frame()
+ {
+ return (struct gc_free_extra_frame *) alloc_gc_frame();
+ }
+
#ifdef PIKE_DEBUG
-
+
+ static unsigned num_gc_stack_frames = 0;
+
+ void debug_free_gc_stack_frame (struct gc_stack_frame *f)
+ {
+ if (f->frameflags & GC_LINK_FREED)
+ gc_fatal (f->data, 0, "Freeing freed gc_stack_frame.\n");
+ f->frameflags |= GC_LINK_FREED;
+ f->s_prev = (struct gc_stack_frame *) (ptrdiff_t) -1;
+ if (f->frameflags |= GC_POP_FRAME) {
+ struct gc_pop_frame *p = (struct gc_pop_frame *) f;
+ p->prev = p->next = (struct gc_pop_frame *)(ptrdiff_t) -1;
+ }
+ really_free_gc_frame ((struct gc_frame *) f);
+ #ifdef GC_VERBOSE
+ num_gc_stack_frames--;
+ #endif
+ }
+
+ static INLINE void FREE_POP_FRAME (struct gc_pop_frame *f) {debug_free_gc_stack_frame ((struct gc_stack_frame *) f);}
+ static INLINE void FREE_LINK_FRAME (struct gc_link_frame *f) {debug_free_gc_stack_frame ((struct gc_stack_frame *) f);}
+ static INLINE void FREE_FREE_EXTRA_FRAME (struct gc_free_extra_frame *f) {really_free_gc_frame ((struct gc_frame *) f);}
+ static INLINE struct gc_stack_frame *POP2STACK (struct gc_pop_frame *f) {return (struct gc_stack_frame *) f;}
+ static INLINE struct gc_stack_frame *LINK2STACK (struct gc_link_frame *f) {return (struct gc_stack_frame *) f;}
+ static INLINE struct gc_pop_frame *STACK2POP (struct gc_stack_frame *f)
+ {
+ if (!(f->frameflags & GC_POP_FRAME)) fatal ("Pop frame expected.\n");
+ return (struct gc_pop_frame *) f;
+ }
+ static INLINE struct gc_link_frame *STACK2LINK (struct gc_stack_frame *f)
+ {
+ if (f->frameflags & GC_POP_FRAME) fatal ("Link frame expected.\n");
+ return (struct gc_link_frame *) f;
+ }
+
+ #else
+
+ #define FREE_POP_FRAME(f) really_free_gc_frame ((struct gc_frame *) f)
+ #define FREE_LINK_FRAME(f) really_free_gc_frame ((struct gc_frame *) f)
+ #define FREE_FREE_EXTRA_FRAME(f) really_free_gc_frame ((struct gc_frame *) f)
+ #define POP2STACK(f) ((struct gc_stack_frame *) f)
+ #define LINK2STACK(f) ((struct gc_stack_frame *) f)
+ #define STACK2POP(f) ((struct gc_pop_frame *) f)
+ #define STACK2LINK(f) ((struct gc_link_frame *) f)
+
+ #endif
+
+ #define gc_frame gc_foo_frame
+
+ #ifdef PIKE_DEBUG
#define CHECK_POP_FRAME(frame) do { \
- if ((frame)->frameflags & GC_LINK_FREED) \
- gc_fatal((frame)->data, 0, "Accessing freed gc_frame.\n"); \
- if (!((frame)->frameflags & GC_POP_FRAME)) \
- gc_fatal((frame)->data, 0, #frame " is not a pop frame.\n"); \
- if (NEXT(PREV(frame)) != (frame)) \
- gc_fatal((frame)->data, 0, \
- "Pop frame pointers are inconsistent.\n"); \
+ struct gc_pop_frame *f_ = (frame); \
+ if (f_->frameflags & GC_LINK_FREED) \
+ gc_fatal (f_->data, 0, "Accessing freed gc_stack_frame.\n"); \
+ if (!(f_->frameflags & GC_POP_FRAME)) \
+ gc_fatal(f_->data, 0, #frame " is not a pop frame.\n"); \
+ if (f_->prev->next != f_) \
+ gc_fatal(f_->data, 0, "Pop frame pointers are inconsistent.\n"); \
} while (0)
#else
#define CHECK_POP_FRAME(frame) do {} while (0)
#endif
- static struct gc_frame rec_list = {0, 0, {{0, 0, 0}}, GC_POP_FRAME};
- static struct gc_frame *gc_rec_last = &rec_list, *gc_rec_top = 0;
- static struct gc_frame *kill_list = 0;
- static struct gc_frame *free_extra_list = 0; /* See note in gc_delayed_free. */
+ static struct gc_pop_frame rec_list = {NULL, NULL, GC_POP_FRAME, 0, NULL, NULL};
+ static struct gc_pop_frame *gc_rec_last = &rec_list;
+ static struct gc_stack_frame *gc_rec_top = NULL;
+ static struct gc_pop_frame *kill_list = NULL;
+ static struct gc_free_extra_frame *free_extra_list = NULL; /* See note in gc_delayed_free. */
static unsigned last_cycle;
size_t gc_ext_weak_refs;
270:
int gc_in_cycle_check = 0;
static unsigned delayed_freed, weak_freed, checked, marked, cycle_checked, live_ref;
- static unsigned max_gc_frames, num_gc_frames = 0, live_rec, frame_rot;
+ static unsigned max_gc_stack_frames, live_rec, frame_rot;
static unsigned gc_extra_refs = 0;
- static unsigned max_tot_gc_frames = 0;
+ static unsigned max_tot_gc_stack_frames = 0;
static unsigned tot_cycle_checked = 0, tot_live_rec = 0, tot_frame_rot = 0;
static int gc_is_watching = 0;
633:
#endif
}
- static void describe_gc_frame(struct gc_frame *l)
+ static void describe_gc_stack_frame (struct gc_stack_frame *f)
{
- if (l->frameflags & GC_POP_FRAME)
- fprintf(stderr, "back=%p, prev=%p, next=%p, data=%p, cycle=%u, flags=0x%02x",
- l->back, PREV(l), NEXT(l), l->data, CYCLE(l), l->frameflags);
- else
- fprintf(stderr, "LINK back=%p, data=%p, weak=%d, flags=0x%02x",
- l->back, l->data, l->u.link.weak, l->frameflags);
+ if (f->frameflags & GC_POP_FRAME) {
+ struct gc_pop_frame *p = STACK2POP (f);
+ fprintf (stderr, "s_prev=%p, data=%p, flags=0x%02x, prev=%p, next=%p, cycle=%u",
+ p->s_prev, p->data, p->frameflags, p->prev, p->next, p->cycle);
}
-
+ else {
+ struct gc_link_frame *l = STACK2LINK (f);
+ fprintf (stderr, "s_prev=%p, data=%p, flags=0x%02x, weak=%d",
+ l->s_prev, l->data, l->frameflags, l->weak);
+ }
+ }
static void describe_marker(struct marker *m)
{
653: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
if (m->frame) {
fputs(" [", stderr);
- describe_gc_frame(m->frame);
+ describe_gc_stack_frame (POP2STACK (m->frame));
putc(']', stderr);
}
#endif
1598:
free_all_gc_frame_blocks();
#ifdef GC_VERBOSE
- num_gc_frames = 0;
+ num_gc_stack_frames = 0;
#endif
#ifdef PIKE_DEBUG
1807: Inside #if defined(PIKE_DEBUG)
return 0;
}
- void debug_really_free_gc_frame(struct gc_frame *l)
- {
- if (l->frameflags & GC_LINK_FREED)
- gc_fatal(l->data, 0, "Freeing freed gc_frame.\n");
- l->frameflags |= GC_LINK_FREED;
- l->back = PREV(l) = NEXT(l) = (struct gc_frame *)(ptrdiff_t) -1;
- really_free_gc_frame(l);
- #ifdef GC_VERBOSE
- num_gc_frames--;
- #endif
- }
-
- #else /* PIKE_DEBUG */
-
- #define debug_really_free_gc_frame(l) really_free_gc_frame(l)
-
+
#endif /* PIKE_DEBUG */
int gc_do_weak_free(void *a)
1922:
*
* Since the value has been marked we won't find it in the free
* pass, so we have to keep special track of it. :P */
- struct gc_frame *l = alloc_gc_frame();
+ struct gc_free_extra_frame *l = alloc_free_extra_frame();
l->data = a;
- l->u.free_extra_type = type;
- l->back = free_extra_list;
- l->frameflags = 0;
+ l->type = type;
+ l->fe_next = free_extra_list;
free_extra_list = l;
}
1990:
PMOD_EXPORT void gc_cycle_enqueue(gc_cycle_check_cb *checkfn, void *data, int weak)
{
- struct gc_frame *l = alloc_gc_frame();
+ struct gc_link_frame *l = alloc_link_frame();
#ifdef PIKE_DEBUG
{
struct marker *m;
2003:
gc_fatal(data, 0, "Use of the gc frame stack outside the cycle check pass.\n");
#endif
#ifdef GC_VERBOSE
- if (++num_gc_frames > max_gc_frames) max_gc_frames = num_gc_frames;
+ if (++num_gc_stack_frames > max_gc_stack_frames)
+ max_gc_stack_frames = num_gc_stack_frames;
#endif
l->data = data;
- l->u.link.checkfn = checkfn;
- l->u.link.weak = weak;
- l->frameflags = 0;
- l->back = gc_rec_top;
+ l->checkfn = checkfn;
+ l->weak = weak;
+ l->s_prev = gc_rec_top;
#ifdef GC_STACK_DEBUG
fprintf(stderr, "enqueue %p [%p]: ", l, gc_rec_top);
- describe_gc_frame(l);
+ describe_gc_stack_frame (LINK2STACK (l));
fputc('\n', stderr);
#endif
- gc_rec_top = l;
+ gc_rec_top = LINK2STACK (l);
}
- static struct gc_frame *gc_cycle_enqueue_pop(void *data)
+ static struct gc_pop_frame *gc_cycle_enqueue_pop(void *data)
{
- struct gc_frame *l = alloc_gc_frame();
+ struct gc_pop_frame *p = alloc_pop_frame();
#ifdef PIKE_DEBUG
if (Pike_in_gc != GC_PASS_CYCLE)
gc_fatal(data, 0, "Use of the gc frame stack outside the cycle check pass.\n");
#endif
#ifdef GC_VERBOSE
- if (++num_gc_frames > max_gc_frames) max_gc_frames = num_gc_frames;
+ if (++num_gc_stack_frames > max_gc_stack_frames)
+ max_gc_stack_frames = num_gc_stack_frames;
#endif
- l->data = data;
- PREV(l) = gc_rec_last;
- NEXT(l) = 0;
- CYCLE(l) = 0;
- l->frameflags = GC_POP_FRAME;
- l->back = gc_rec_top;
+ p->data = data;
+ p->prev = gc_rec_last;
+ p->next = 0;
+ p->cycle = 0;
+ p->s_prev = gc_rec_top;
#ifdef GC_STACK_DEBUG
- fprintf(stderr, "enqueue %p [%p]: ", l, gc_rec_top);
- describe_gc_frame(l);
+ fprintf(stderr, "enqueue %p [%p]: ", p, gc_rec_top);
+ describe_gc_stack_frame (POP2STACK (p));
fputc('\n', stderr);
#endif
- gc_rec_top = l;
- return l;
+ gc_rec_top = POP2STACK (p);
+ return p;
}
void gc_cycle_run_queue()
2051:
#endif
while (gc_rec_top) {
#ifdef GC_STACK_DEBUG
- fprintf(stderr, "dequeue %p [%p]: ", gc_rec_top, gc_rec_top->back);
- describe_gc_frame(gc_rec_top);
+ fprintf(stderr, "dequeue %p [%p]: ", gc_rec_top, gc_rec_top->s_prev);
+ describe_gc_stack_frame(gc_rec_top);
fputc('\n', stderr);
#endif
if (gc_rec_top->frameflags & GC_POP_FRAME) {
- struct gc_frame *l = gc_rec_top->back;
- gc_cycle_pop(gc_rec_top->data);
- gc_rec_top = l;
+ struct gc_stack_frame *f = gc_rec_top->s_prev;
+ gc_cycle_pop (gc_rec_top->data);
+ gc_rec_top = f;
} else {
- struct gc_frame l = *gc_rec_top;
+ struct gc_link_frame l = *STACK2LINK (gc_rec_top);
#ifdef PIKE_DEBUG
if (l.frameflags & GC_LINK_FREED)
gc_fatal(l.data, 0, "Accessing freed gc_frame.\n");
#endif
- debug_really_free_gc_frame(gc_rec_top);
- gc_rec_top = l.back;
- l.u.link.checkfn(l.data, l.u.link.weak);
+ FREE_LINK_FRAME (STACK2LINK (gc_rec_top));
+ gc_rec_top = l.s_prev;
+ l.checkfn (l.data, l.weak);
}
}
}
2083:
#define CYCLE_DEBUG_MSG(M, TXT) do {} while (0)
#endif
- static void rotate_rec_list (struct gc_frame *beg, struct gc_frame *pos)
+ static void rotate_rec_list (struct gc_pop_frame *beg, struct gc_pop_frame *pos)
/* Rotates the marker list and the cycle stack so the bit from pos
* down to the end gets before the bit from beg down to pos. The beg
* pos might be moved further down the stack to avoid mixing cycles or
* breaking strong link sequences. */
{
#ifdef GC_STACK_DEBUG
- struct gc_frame *l;
+ struct gc_stack_frame *l;
#endif
CYCLE_DEBUG_MSG(find_marker(beg->data), "> rotate_rec_list, asked to begin at");
2101: Inside #if defined(PIKE_DEBUG)
CHECK_POP_FRAME(pos);
if (beg == pos)
gc_fatal(beg->data, 0, "Cycle already broken at requested position.\n");
- if (NEXT(gc_rec_last))
+ if (gc_rec_last->next)
gc_fatal(gc_rec_last->data, 0, "gc_rec_last not at end.\n");
#endif
#ifdef GC_STACK_DEBUG
fprintf(stderr,"Stack before:\n");
- for (l = gc_rec_top; l; l = l->back) {
+ for (l = gc_rec_top; l; l = l->s_prev) {
fprintf(stderr, " %p ", l);
- describe_gc_frame(l);
+ describe_gc_stack_frame(l);
fputc('\n', stderr);
}
#endif
#if 0
- if (CYCLE(beg)) {
- for (l = beg; CYCLE(PREV(l)) == CYCLE(beg); l = PREV(l))
+ if (beg->cycle) {
+ for (l = beg; l->prev->cycle == beg->cycle; l = l->prev)
CHECK_POP_FRAME(l);
- if (CYCLE(l) == CYCLE(pos)) {
+ if (l->cycle == pos->cycle) {
/* Breaking something previously marked as a cycle. Clear it
* since we're no longer sure it's an unambiguous cycle. */
- unsigned cycle = CYCLE(l);
- for (; l && CYCLE(l) == cycle; l = NEXT(l)) {
+ unsigned cycle = l->cycle;
+ for (; l && l->cycle == cycle; l = l->next) {
CHECK_POP_FRAME(l);
#ifdef GC_CYCLE_DEBUG
- if (CYCLE(l))
+ if (l->cycle)
CYCLE_DEBUG_MSG(find_marker(l->data), "> rotate_rec_list, clear cycle");
#endif
- CYCLE(l) = 0;
+ l->cycle = 0;
}
}
else beg = l; /* Keep the cycle continuous. */
2137:
/* Always keep chains of strong refs continuous, or else we risk
* breaking the order in a later rotation. */
- for (; beg->frameflags & GC_STRONG_REF; beg = PREV(beg)) {}
+ for (; beg->frameflags & GC_STRONG_REF; beg = beg->prev) {}
CYCLE_DEBUG_MSG(find_marker(beg->data), "> rotate_rec_list, begin at");
{
- struct gc_frame *b = beg, *p = pos, *old_rec_top;
+ struct gc_pop_frame *b = beg, *p = pos;
+ struct gc_stack_frame *old_rec_top;
while (b->frameflags & GC_OFF_STACK) {
- if ((b = NEXT(b)) == pos) goto done;
+ if ((b = b->next) == pos) goto done;
CHECK_POP_FRAME(b);
DO_IF_DEBUG(frame_rot++);
}
while (p->frameflags & GC_OFF_STACK) {
- if (!(p = NEXT(p))) goto done;
+ if (!(p = p->next)) goto done;
CHECK_POP_FRAME(p);
DO_IF_DEBUG(frame_rot++);
}
old_rec_top = gc_rec_top;
- gc_rec_top = p->back;
- p->back = b->back;
- b->back = old_rec_top;
+ gc_rec_top = p->s_prev;
+ p->s_prev = b->s_prev;
+ b->s_prev = old_rec_top;
}
done:
DO_IF_DEBUG(frame_rot++);
{
- struct gc_frame *new_rec_last = PREV(pos);
- NEXT(PREV(beg)) = pos;
- PREV(pos) = PREV(beg);
- NEXT(gc_rec_last) = beg;
- PREV(beg) = gc_rec_last;
+ struct gc_pop_frame *new_rec_last = pos->prev;
+ beg->prev->next = pos;
+ pos->prev = beg->prev;
+ gc_rec_last->next = beg;
+ beg->prev = gc_rec_last;
gc_rec_last = new_rec_last;
- NEXT(gc_rec_last) = 0;
+ gc_rec_last->next = 0;
}
if (beg->frameflags & GC_WEAK_REF) {
2179: Inside #if defined(GC_STACK_DEBUG)
#ifdef GC_STACK_DEBUG
fprintf(stderr,"Stack after:\n");
- for (l = gc_rec_top; l; l = l->back) {
+ for (l = gc_rec_top; l; l = l->s_prev) {
fprintf(stderr, " %p ", l);
- describe_gc_frame(l);
+ describe_gc_stack_frame(l);
fputc('\n', stderr);
}
#endif
2262:
CYCLE_DEBUG_MSG(m, "gc_cycle_push, no live recurse");
last->flags &= ~GC_LIVE_RECURSE;
while (1) {
- struct gc_frame *l = gc_rec_top;
+ struct gc_stack_frame *l = gc_rec_top;
#ifdef PIKE_DEBUG
if (!gc_rec_top)
Pike_fatal("Expected a gc_cycle_pop entry in gc_rec_top.\n");
#endif
- gc_rec_top = l->back;
+ gc_rec_top = l->s_prev;
if (l->frameflags & GC_POP_FRAME) {
- gc_rec_last = PREV(l);
- debug_really_free_gc_frame(l);
+ gc_rec_last = STACK2POP (l)->prev;
+ FREE_POP_FRAME (STACK2POP (l));
break;
}
- debug_really_free_gc_frame(l);
+ FREE_LINK_FRAME (STACK2LINK (l));
}
#ifdef GC_CYCLE_DEBUG
gc_cycle_indent -= 2;
2300:
#endif
if (m != last) {
- struct gc_frame *p, *weak_ref = 0, *nonstrong_ref = 0;
+ struct gc_pop_frame *p, *weak_ref = 0, *nonstrong_ref = 0;
if (!weak) {
- struct gc_frame *q;
+ struct gc_pop_frame *q;
CYCLE_DEBUG_MSG(m, "gc_cycle_push, search normal");
/* Find the last weakly linked thing and the one before the
* first strongly linked thing. */
- for (q = m->frame, p = NEXT(q);; q = p, p = NEXT(p)) {
+ for (q = m->frame, p = q->next;; q = p, p = p->next) {
CHECK_POP_FRAME(p);
if (p->frameflags & (GC_WEAK_REF|GC_STRONG_REF)) {
if (p->frameflags & GC_WEAK_REF) weak_ref = p;
2320:
CYCLE_DEBUG_MSG(m, "gc_cycle_push, search strong");
/* Find the last weakly linked thing and the last one which
* isn't strongly linked. */
- for (p = NEXT(m->frame);; p = NEXT(p)) {
+ for (p = m->frame->next;; p = p->next) {
CHECK_POP_FRAME(p);
if (p->frameflags & GC_WEAK_REF) weak_ref = p;
if (!(p->frameflags & GC_STRONG_REF)) nonstrong_ref = p;
2329: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
if (p == gc_rec_last && !nonstrong_ref) {
fprintf(stderr, "Only strong links in cycle:\n");
- for (p = m->frame;; p = NEXT(p)) {
+ for (p = m->frame;; p = p->next) {
describe(p->data);
locate_references(p->data);
if (p == gc_rec_last) break;
2341:
}
else {
- struct gc_frame *q;
+ struct gc_pop_frame *q;
CYCLE_DEBUG_MSG(m, "gc_cycle_push, search weak");
/* Find the thing before the first strongly linked one. */
- for (q = m->frame, p = NEXT(q);; q = p, p = NEXT(p)) {
+ for (q = m->frame, p = q->next;; q = p, p = p->next) {
CHECK_POP_FRAME(p);
if (!(p->frameflags & GC_WEAK_REF) && !nonstrong_ref)
nonstrong_ref = q;
2368:
CYCLE_DEBUG_MSG(find_marker(nonstrong_ref->data),
"gc_cycle_push, nonstrong break");
rotate_rec_list(m->frame, nonstrong_ref);
- NEXT(nonstrong_ref)->frameflags =
- (NEXT(nonstrong_ref)->frameflags & ~GC_WEAK_REF) | GC_STRONG_REF;
+ nonstrong_ref->next->frameflags =
+ (nonstrong_ref->next->frameflags & ~GC_WEAK_REF) | GC_STRONG_REF;
}
else if (nonstrong_ref) {
2387:
/* A normal cycle which will be destructed in arbitrary
* order. For reasons having to do with strong links we
* can't mark weak cycles this way. */
- unsigned cycle = CYCLE(m->frame) ? CYCLE(m->frame) : ++last_cycle;
- if (cycle == CYCLE(gc_rec_last))
+ unsigned cycle = m->frame->cycle ? m->frame->cycle : ++last_cycle;
+ if (cycle == gc_rec_last->cycle)
CYCLE_DEBUG_MSG(m, "gc_cycle_push, old cycle");
else {
CYCLE_DEBUG_MSG(m, "gc_cycle_push, cycle");
- for (p = m->frame;; p = NEXT(p)) {
- CYCLE(p) = cycle;
+ for (p = m->frame;; p = p->next) {
+ p->cycle = cycle;
CYCLE_DEBUG_MSG(find_marker(p->data), "> gc_cycle_push, mark cycle");
if (p == gc_rec_last) break;
}}}}} /* Mmm.. lisp ;) */
else
if (!(m->flags & GC_CYCLE_CHECKED)) {
- struct gc_frame *l;
+ struct gc_pop_frame *l;
#ifdef PIKE_DEBUG
cycle_checked++;
if (m->frame)
gc_fatal(x, 0, "Marker already got a frame.\n");
- if (NEXT(gc_rec_last))
+ if (gc_rec_last->next)
gc_fatal(gc_rec_last->data, 0, "Not at end of list.\n");
#endif
- NEXT(gc_rec_last) = m->frame = l = gc_cycle_enqueue_pop(x);
+ gc_rec_last->next = m->frame = l = gc_cycle_enqueue_pop(x);
m->flags |= GC_CYCLE_CHECKED | (last->flags & GC_LIVE);
debug_malloc_touch(x);
if (weak) {
2455:
{
/* Recurse without linking onto rec_list. */
- struct gc_frame *l = gc_cycle_enqueue_pop(x);
+ struct gc_pop_frame *l = gc_cycle_enqueue_pop(x);
#ifdef GC_CYCLE_DEBUG
CYCLE_DEBUG_MSG(m, "gc_cycle_push, live recurse");
gc_cycle_indent += 2;
2472:
static void gc_cycle_pop(void *a)
{
struct marker *m = find_marker(a);
- struct gc_frame *here, *base, *p;
+ struct gc_pop_frame *here, *base, *p;
#ifdef PIKE_DEBUG
if (gc_is_watching && m && m->flags & GC_WATCHED) {
2500:
if (m->flags & GC_LIVE_RECURSE) {
m->flags &= ~GC_LIVE_RECURSE;
CYCLE_DEBUG_MSG(m, "gc_cycle_pop_live");
- gc_rec_last = PREV(gc_rec_top);
- debug_really_free_gc_frame(gc_rec_top);
+ gc_rec_last = STACK2POP (gc_rec_top)->prev;
+ FREE_POP_FRAME (STACK2POP (gc_rec_top));
return;
}
2513: Inside #if defined(PIKE_DEBUG)
CHECK_POP_FRAME(gc_rec_last);
if (here->frameflags & GC_OFF_STACK)
gc_fatal(a, 0, "Marker being popped isn't on stack.\n");
- here->back = (struct gc_frame *)(ptrdiff_t) -1;
+ here->s_prev = (struct gc_stack_frame *)(ptrdiff_t) -1;
#endif
here->frameflags |= GC_OFF_STACK;
- for (base = PREV(here), p = here;; base = p, p = NEXT(p)) {
+ for (base = here->prev, p = here;; base = p, p = p->next) {
if (base == here) {
/* Part of a cycle; wait until the cycle is complete before
* unlinking it from rec_list. */
- DO_IF_DEBUG(m->frame->back = (struct gc_frame *)(ptrdiff_t) -1);
+ DO_IF_DEBUG(m->frame->s_prev = (struct gc_stack_frame *)(ptrdiff_t) -1);
CYCLE_DEBUG_MSG(m, "gc_cycle_pop, keep cycle");
return;
}
CHECK_POP_FRAME(p);
- if (!(CYCLE(p) && CYCLE(p) == CYCLE(base)))
+ if (!(p->cycle && p->cycle == base->cycle))
break;
}
gc_rec_last = base;
- while ((p = NEXT(base))) {
+ while ((p = base->next)) {
struct marker *pm = find_marker(p->data);
#ifdef PIKE_DEBUG
if (pm->frame != p)
2545:
gc_add_extra_ref(p->data);
base = p;
p->frameflags |= GC_ON_KILL_LIST;
- DO_IF_DEBUG(PREV(p) = (struct gc_frame *)(ptrdiff_t) -1);
+ DO_IF_DEBUG(p->prev = (struct gc_pop_frame *)(ptrdiff_t) -1);
CYCLE_DEBUG_MSG(pm, "gc_cycle_pop, put on kill list");
}
else {
2564: Inside #if defined(PIKE_DEBUG)
if (pm->flags & GC_GOT_DEAD_REF)
gc_fatal(p->data, 0, "Didn't expect a dead extra ref.\n");
#endif
- NEXT(base) = NEXT(p);
+ base->next = p->next;
CYCLE_DEBUG_MSG(pm, "gc_cycle_pop, pop off");
pm->frame = 0;
- debug_really_free_gc_frame(p);
+ FREE_POP_FRAME (p);
}
}
if (base != gc_rec_last) {
- NEXT(base) = kill_list;
- kill_list = NEXT(gc_rec_last);
- NEXT(gc_rec_last) = 0;
+ base->next = kill_list;
+ kill_list = gc_rec_last->next;
+ gc_rec_last->next = 0;
}
}
2696:
SET_ONERROR(tmp, free_obj_arr, obj_arr_);
{
- struct gc_frame *p;
+ struct gc_pop_frame *p;
unsigned cycle = 0;
*obj_arr_ = allocate_array(0);
for (p = kill_list; p;) {
- if ((cycle = CYCLE(p))) {
+ if ((cycle = p->cycle)) {
push_object((struct object *) p->data);
dmalloc_touch_svalue(Pike_sp-1);
*obj_arr_ = append_array(*obj_arr_, --Pike_sp);
}
- p = NEXT(p);
- if (p ? ((unsigned)(CYCLE(p) != cycle)) : cycle) {
+ p = p->next;
+ if (p ? ((unsigned)(p->cycle != cycle)) : cycle) {
if ((*obj_arr_)->size >= 2) {
push_constant_text("gc");
push_constant_text("bad_cycle");
2884: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
size_t orig_ext_weak_refs = gc_ext_weak_refs;
obj_count = delayed_freed;
- max_gc_frames = 0;
+ max_gc_stack_frames = 0;
#endif
Pike_in_gc=GC_PASS_CYCLE;
2903: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
if (gc_rec_top)
Pike_fatal("gc_rec_top not empty at end of cycle check pass.\n");
- if (NEXT(&rec_list) || gc_rec_last != &rec_list || gc_rec_top)
+ if (rec_list.next || gc_rec_last != &rec_list || gc_rec_top)
Pike_fatal("Recurse list not empty or inconsistent after cycle check pass.\n");
if (gc_ext_weak_refs != orig_ext_weak_refs)
Pike_fatal("gc_ext_weak_refs changed from %"PRINTSIZET"u "
2918:
"| space for %u gc frames used\n",
cycle_checked, last_cycle, weak_freed,
delayed_freed - obj_count,
- live_rec, frame_rot, max_gc_frames));
+ live_rec, frame_rot, max_gc_stack_frames));
}
if (gc_ext_weak_refs) {
3013:
/* We might occasionally get things to gc_delayed_free that the free
* calls above won't find. They're tracked in this list. */
while (free_extra_list) {
- struct gc_frame *next = free_extra_list->back;
+ struct gc_free_extra_frame *next = free_extra_list->fe_next;
union anything u;
u.refs = (INT32 *) free_extra_list->data;
- gc_free_extra_ref(u.refs);
- free_short_svalue(&u, free_extra_list->u.free_extra_type);
- debug_really_free_gc_frame(free_extra_list);
+ gc_free_extra_ref (u.refs);
+ free_short_svalue (&u, free_extra_list->type);
+ FREE_FREE_EXTRA_FRAME (free_extra_list);
free_extra_list = next;
}
3056:
#endif
DESTRUCT_GC;
while (kill_list) {
- struct gc_frame *next = NEXT(kill_list);
+ struct gc_pop_frame *next = kill_list->next;
struct object *o = (struct object *) kill_list->data;
#ifdef PIKE_DEBUG
if (!(kill_list->frameflags & GC_ON_KILL_LIST))
3086: Inside #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
#if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
destroy_count++;
#endif
- debug_really_free_gc_frame(kill_list);
+ FREE_POP_FRAME (kill_list);
kill_list = next;
}
}
3256: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
UNSET_ONERROR (uwp);
- if (max_gc_frames > max_tot_gc_frames) max_tot_gc_frames = max_gc_frames;
+ if (max_gc_stack_frames > max_tot_gc_stack_frames)
+ max_tot_gc_stack_frames = max_gc_stack_frames;
tot_cycle_checked += cycle_checked;
tot_live_rec += live_rec, tot_frame_rot += frame_rot;
#endif
3402:
"???");
#ifdef PIKE_DEBUG
- fprintf(stderr,"Max used gc frames : %u\n", max_tot_gc_frames);
+ fprintf(stderr,"Max used gc frames : %u\n", max_tot_gc_stack_frames);
fprintf(stderr,"Live recursed ratio : %g\n",
(double) tot_live_rec / tot_cycle_checked);
fprintf(stderr,"Frame rotation ratio : %g\n",