pike.git / src / gc.c

version» Context lines:

pike.git/src/gc.c:23:   #include "constants.h"   #include "interpret.h"   #include "bignum.h"      #include "gc.h"   #include "main.h"   #include <math.h>      #include "block_alloc.h"    - RCSID("$Id: gc.c,v 1.133 2000/09/14 15:25:36 mast Exp $"); + RCSID("$Id: gc.c,v 1.134 2000/09/15 00:30:55 mast Exp $");      /* Run garbage collect approximately every time    * 20 percent of all arrays, objects and programs is    * garbage.    */      #define GC_CONST 20   #define MIN_ALLOC_THRESHOLD 1000   #define MAX_ALLOC_THRESHOLD 10000000   #define MULTIPLIER 0.9
pike.git/src/gc.c:1200: Inside #if defined(PIKE_DEBUG)
   else m = get_marker(a);    debug_malloc_touch(a);       if (m->weak_refs > m->refs)    gc_fatal(a, 0, "More weak references than internal references.\n");   #else    m = get_marker(a);   #endif       if (Pike_in_gc != GC_PASS_ZAP_WEAK) { -  if (m->weak_refs < 0) { -  gc_ext_weak_refs--; - #ifdef PIKE_DEBUG -  m->flags |= GC_WEAK_FREED; - #endif -  return 1; +  if (m->weak_refs < 0) +  goto should_free;    } -  } +     else    if (!(m->flags & GC_MARKED)) {   #ifdef PIKE_DEBUG    if (m->weak_refs <= 0)    gc_fatal(a, 0, "Too many weak refs cleared to thing with external "    "weak refs.\n");   #endif    m->weak_refs--; -  +  goto should_free; +  } +  return 0; +  + should_free:    gc_ext_weak_refs--;   #ifdef PIKE_DEBUG    m->flags |= GC_WEAK_FREED;   #endif -  +  +  if (*(INT32 *) a == 1) { +  /* Make sure the thing doesn't run out of refs, since we can't +  * handle cascading frees now. We'll do it in the free pass +  * instead. */ +  gc_add_extra_ref(a); +  m->flags |= GC_GOT_DEAD_REF; +  } +     return 1;   } -  return 0; - } +       int gc_mark(void *a)   {    struct marker *m = get_marker(debug_malloc_pass(a));      #ifdef PIKE_DEBUG    if (!a) fatal("Got null pointer.\n");    if (Pike_in_gc != GC_PASS_MARK && Pike_in_gc != GC_PASS_ZAP_WEAK)    fatal("gc mark attempted in invalid pass.\n");    if (!*(INT32 *) a)
pike.git/src/gc.c:1771:    if (!(CYCLE(p) && CYCLE(p) == CYCLE(base)))    break;    }       gc_rec_last = base;    while ((p = NEXT(base))) {    struct marker *pm = find_marker(p->data);   #ifdef PIKE_DEBUG    if (pm->frame != p)    gc_fatal(p->data, 0, "Bogus marker for thing being popped.\n"); -  if (pm->flags & GC_GOT_DEAD_REF) -  gc_fatal(p->data, 0, "Didn't expect a dead extra ref.\n"); +    #endif    p->frameflags &= ~(GC_WEAK_REF|GC_STRONG_REF);    if (pm->flags & GC_LIVE_OBJ) { -  /* This extra ref is taken away in the kill pass. */ +  /* This extra ref is taken away in the kill pass. Don't add one +  * if it got an extra ref already due to weak free. */ +  if (!(pm->flags & GC_GOT_DEAD_REF))    gc_add_extra_ref(p->data);    base = p;    DO_IF_DEBUG(PREV(p) = (struct gc_frame *)(ptrdiff_t) -1);    CYCLE_DEBUG_MSG(pm, "gc_cycle_pop, put on kill list");    }    else {    if (!(pm->flags & GC_LIVE)) {    /* Add an extra ref which is taken away in the free pass. This    * is done to not refcount garb the cycles themselves    * recursively, which in bad cases can consume a lot of C    * stack. */ - #ifdef PIKE_DEBUG -  if (pm->flags & GC_GOT_DEAD_REF) -  gc_fatal(pm->data, 0, -  "A thing already got an extra dead cycle ref.\n"); - #endif +  if (!(pm->flags & GC_GOT_DEAD_REF)) {    gc_add_extra_ref(pm->data);    pm->flags |= GC_GOT_DEAD_REF;    } -  +  } + #ifdef PIKE_DEBUG +  else +  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);    CYCLE_DEBUG_MSG(pm, "gc_cycle_pop, pop off");    pm->frame = 0;    debug_really_free_gc_frame(p);    }    }       if (base != gc_rec_last) {    NEXT(base) = kill_list;    kill_list = NEXT(gc_rec_last);