Branch: Tag:

2003-01-29

2003-01-29 15:55:26 by Martin Stjernholm <mast@lysator.liu.se>

Enabled some consistency checks in the gc when compiled without rtldebug
(only activated on debug level 1 or higher). Always define _verify_internals
to be able to use this. Made it possible to turn on trace messages for the
gc only with trace(1,"gc").

Rev: src/array.c:1.108
Rev: src/builtin.cmod:1.31
Rev: src/builtin_functions.c:1.367
Rev: src/gc.c:1.152
Rev: src/gc.h:1.76
Rev: src/mapping.c:1.125
Rev: src/multiset.c:1.34
Rev: src/object.c:1.165
Rev: src/program.c:1.316

30:      #include "block_alloc.h"    - RCSID("$Id: gc.c,v 1.151 2003/01/12 17:25:31 mast Exp $"); + RCSID("$Id: gc.c,v 1.152 2003/01/29 15:55:25 mast Exp $");      /* Run garbage collect approximately every time    * 20 percent of all arrays, objects and programs is
101:   PMOD_EXPORT int Pike_in_gc = 0;   struct pike_queue gc_mark_queue;   time_t last_gc; + int gc_trace = 0, gc_debug = 0;      struct gc_frame   {
296:   static int found_in_type=0;   void *gc_svalue_location=0;   char *fatal_after_gc=0; - int gc_debug = 0; +       #define DESCRIBE_MEM 1   #define DESCRIBE_NO_REFS 2
523:    fprintf(stderr, "no marker\n");   }    + #endif /* PIKE_DEBUG */ +    void debug_gc_fatal(void *a, int flags, const char *fmt, ...)   {    va_list args;
534:       va_end(args);    + #ifdef PIKE_DEBUG    describe(a);    if (flags & 1) locate_references(a);    if (flags & 2)    fatal_after_gc = "Fatal in garbage collector.\n";    else -  + #endif    debug_fatal("Fatal in garbage collector.\n");   }    -  + #ifdef PIKE_DEBUG +    static void gdb_gc_stop_here(void *a, int weak)   {    fprintf(stderr,"***One %sref found%s. ",
854:    describe_something(s->u.refs,s->type,0,2,0);   }    + #endif /* PIKE_DEBUG */ +    void debug_gc_touch(void *a)   {    struct marker *m;
885:    else if (m->flags & GC_LIVE_RECURSE ||    (m->frame && m->frame->frameflags & (GC_WEAK_REF|GC_STRONG_REF)))    gc_fatal(a, 2, "Thing still got flag from recurse list.\n"); + #ifdef PIKE_DEBUG    else if (m->flags & GC_MARKED)    return;    else if (!(m->flags & GC_NOT_REFERENCED) || m->flags & GC_XREFERENCED)
910:    else    gc_fatal(a, 3, "A thing to garb is still around.\n");    } + #endif    }    break;   
918:    }   }    + #ifdef PIKE_DEBUG +    static INLINE struct marker *gc_check_debug(void *a, int weak)   {    struct marker *m;
1985:    if(Pike_in_gc) return 0;    init_gc();    Pike_in_gc=GC_PASS_PREPARE; - #ifdef PIKE_DEBUG +     gc_debug = d_flag; -  + #ifdef PIKE_DEBUG    SET_ONERROR(uwp, fatal_on_error, "Shouldn't get an exception inside the gc.\n");   #endif   
2001:    objs=num_objects;    last_cycle = 0;    - #ifdef PIKE_DEBUG -  if(GC_VERBOSE_DO(1 ||) t_flag) { +  if(GC_VERBOSE_DO(1 ||) gc_trace) {    fprintf(stderr,"Garbage collecting ... ");    GC_VERBOSE_DO(fprintf(stderr, "\n"));   #ifdef HAVE_GETHRTIME    gcstarttime = gethrtime();   #endif    } -  + #ifdef PIKE_DEBUG    if(num_objects < 0)    fatal("Panic, less than zero objects!\n");   #endif
2028: Inside #if defined(PIKE_DEBUG)
     #ifdef PIKE_DEBUG    weak_freed = checked = marked = cycle_checked = live_ref = 0; + #endif    if (gc_debug) {    unsigned n;    Pike_in_gc = GC_PASS_PRETOUCH;
2036: Inside #if defined(PIKE_DEBUG)
   n += gc_touch_all_mappings();    n += gc_touch_all_programs();    n += gc_touch_all_objects(); + #ifdef PIKE_DEBUG    gc_touch_all_strings(); -  + #endif    if (n != (unsigned) num_objects)    fatal("Object count wrong before gc; expected %d, got %d.\n", num_objects, n);    GC_VERBOSE_DO(fprintf(stderr, "| pretouch: %u things\n", n));    } - #endif +        Pike_in_gc=GC_PASS_CHECK;    gc_ext_weak_refs = 0;
2143:    obj_count - num_objects, max_gc_frames));    }    - #ifdef PIKE_DEBUG +     if (gc_debug) {    unsigned n;    size_t i;
2154: Inside #if defined(PIKE_DEBUG)
   n += gc_touch_all_mappings();    n += gc_touch_all_programs();    n += gc_touch_all_objects(); + #ifdef PIKE_DEBUG    gc_touch_all_strings(); -  + #endif    if (n != (unsigned) num_objects)    fatal("Object count wrong in gc; expected %d, got %d.\n", num_objects, n);    get_marker(rec_list.data)->flags |= GC_MIDDLETOUCHED;   #if 0 -  + #ifdef PIKE_DEBUG   #ifdef DEBUG_MALLOC    PTR_HASH_LOOP(marker, i, m)    if (!(m->flags & (GC_MIDDLETOUCHED|GC_WEAK_FREED)) &&
2173: Inside #if defined(PIKE_DEBUG) and #if 0
   }   #endif   #endif + #endif    GC_VERBOSE_DO(fprintf(stderr, "| middletouch\n"));    } - #endif +        if (gc_ext_weak_refs) {    size_t to_free = gc_ext_weak_refs;
2312:    GC_VERBOSE_DO(fprintf(stderr, "| destruct: %d things really freed\n",    obj_count - num_objects));    - #ifdef PIKE_DEBUG +     if (gc_debug) {    unsigned n;    Pike_in_gc=GC_PASS_POSTTOUCH;
2326: Inside #if defined(PIKE_DEBUG)
   fatal("Object count wrong after gc; expected %d, got %d.\n", num_objects, n);    GC_VERBOSE_DO(fprintf(stderr, "| posttouch: %u things\n", n));    } + #ifdef PIKE_DEBUG    if (gc_extra_refs)    fatal("Lost track of %d extra refs to things in gc.\n", gc_extra_refs);    if(fatal_after_gc) fatal("%s", fatal_after_gc);
2359: Inside #if defined(PIKE_DEBUG)
     #ifdef PIKE_DEBUG    UNSET_ONERROR (uwp); -  if(GC_VERBOSE_DO(1 ||) t_flag) + #endif +  if(GC_VERBOSE_DO(1 ||) gc_trace)    {   #ifdef HAVE_GETHRTIME    fprintf(stderr,"done (freed %d of %d objects), %ld ms.\n",
2370:    (int)objs,start_num_objs);   #endif    } - #endif +       #ifdef ALWAYS_GC    ADD_GC_CALLBACK();