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.158 2001/06/29 01:21:52 mast Exp $"); + RCSID("$Id: gc.c,v 1.159 2001/06/30 02:35:50 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:710:    (flags | DESCRIBE_SHORT | DESCRIBE_NO_REFS )    & ~ (DESCRIBE_MEM));    }else{    fprintf(stderr,"%*s**There is no parent (any longer?)\n",indent,"");    }    break;       case T_PROGRAM:    {    char *tmp; -  INT32 line,pos; +  INT32 line;    int foo=0;       fprintf(stderr,"%*s**Program id: %ld, flags: %x\n",indent,"",    (long)(p->id),    p->flags);       if(p->flags & PROGRAM_HAS_C_METHODS)    {    fprintf(stderr,"%*s**The program was written in C.\n",indent,"");    } -  for(pos=0;pos<100;pos++) +  tmp=get_program_line(p, &line); +  if(strcmp(tmp, "-"))    { -  tmp=get_line(p->program+pos, p, &line); -  if(tmp && line) -  { +     fprintf(stderr,"%*s**Location: %s:%ld\n",indent,"",tmp,(long)line);    foo=1;    break;    } -  if(pos+1>=(ptrdiff_t)p->num_program) -  break; -  } +    #if 0    if(!foo && p->num_linenumbers>1 && EXTRACT_UCHAR(p->linenumbers)=='\177')    {    fprintf(stderr,"%*s**From file: %s\n",indent,"",p->linenumbers+1);    foo=1;    }   #endif       if(!foo)    {
pike.git/src/gc.c:901:   void debug_gc_touch(void *a)   {    struct marker *m;    if (!a) fatal("Got null pointer.\n");       switch (Pike_in_gc) {    case GC_PASS_PRETOUCH:    m = find_marker(a);    if (m && !(m->flags & GC_PRETOUCHED))    gc_fatal(a, 1, "Thing got an existing but untouched marker.\n"); -  get_marker(a)->flags |= GC_PRETOUCHED; +  m = get_marker(a); +  m->flags |= GC_PRETOUCHED; +  m->saved_refs = *(INT32 *) a;    break;    -  case GC_PASS_MIDDLETOUCH: +  case GC_PASS_MIDDLETOUCH: { +  int extra_ref;    m = find_marker(a);    if (!m)    gc_fatal(a, 1, "Found a thing without marker.\n");    else if (!(m->flags & GC_PRETOUCHED))    gc_fatal(a, 1, "Thing got an existing but untouched marker.\n"); -  +  extra_ref = (m->flags & GC_GOT_EXTRA_REF) == GC_GOT_EXTRA_REF; +  if (m->saved_refs + extra_ref < *(INT32 *) a) +  if (m->flags & GC_WEAK_FREED) +  gc_fatal(a, 1, "Something failed to remove weak reference(s) to thing, " +  "or it has gotten more references since gc start.\n"); +  else +  gc_fatal(a, 1, "Thing has gotten more references since gc start.\n"); +  else if (m->weak_refs > m->saved_refs) +  gc_fatal(a, 0, "A thing got more weak references than references.\n");    m->flags |= GC_MIDDLETOUCHED;    break; -  +  }       case GC_PASS_POSTTOUCH:    m = find_marker(a);    if (!*(INT32 *) a)    gc_fatal(a, 1, "Found a thing without refs.\n");    if (m) {    if (!(m->flags & (GC_PRETOUCHED|GC_MIDDLETOUCHED)))    gc_fatal(a, 2, "An existing but untouched marker found "    "for object in linked lists.\n");    else if (m->flags & GC_LIVE_RECURSE ||
pike.git/src/gc.c:978:    return 0;    }       if (Pike_in_gc != GC_PASS_CHECK)    fatal("gc check attempted in invalid pass.\n");       m = get_marker(a);       if (!*(INT32 *)a)    gc_fatal(a, 1, "GC check on thing without refs.\n"); -  if (m->saved_refs != -1 && m->saved_refs != *(INT32 *)a) +  if (m->saved_refs == -1) m->saved_refs = *(INT32 *)a; +  else if (m->saved_refs != *(INT32 *)a)    gc_fatal(a, 1, "Refs changed in gc check pass.\n"); -  m->saved_refs = *(INT32 *)a; +     if (m->refs + m->xrefs >= *(INT32 *) a)    /* m->refs will be incremented by the caller. */    gc_fatal(a, 1, "Thing is getting more internal refs than refs.\n");    checked++;       return m;   }      #endif /* PIKE_DEBUG */   
pike.git/src/gc.c:1004:    INT32 ret;      #ifdef PIKE_DEBUG    if (!(m = gc_check_debug(a, 0))) return 0;   #else    m = get_marker(a);   #endif       ret=m->refs;    add_ref(m); -  if (m->refs >= *(INT32 *) a) +  if (m->refs == *(INT32 *) a)    m->flags |= GC_NOT_REFERENCED;    return ret;   }      INT32 real_gc_check_weak(void *a)   {    struct marker *m;    INT32 ret;      #ifdef PIKE_DEBUG
pike.git/src/gc.c:1028: Inside #if defined(PIKE_DEBUG)
   if (m->weak_refs >= *(INT32 *) a)    gc_fatal(a, 1, "Thing has gotten more weak refs than refs.\n");    if (m->weak_refs > m->refs + 1)    gc_fatal(a, 1, "Thing has gotten more weak refs than internal refs.\n");   #else    m = get_marker(a);   #endif       m->weak_refs++;    gc_ext_weak_refs++; -  if (m->weak_refs >= *(INT32 *) a) +  if (m->weak_refs == *(INT32 *) a)    m->weak_refs = -1;       ret=m->refs;    add_ref(m); -  if (m->refs >= *(INT32 *) a) +  if (m->refs == *(INT32 *) a)    m->flags |= GC_NOT_REFERENCED;    return ret;   }      static void init_gc(void)   {    init_marker_hash();    get_marker(rec_list.data); /* Used to simplify fencepost conditions. */   }   
pike.git/src/gc.c:2199:   #endif       GC_VERBOSE_DO(fprintf(stderr,    "| cycle: %u internal things visited, %u cycle ids used,\n"    "| %u weak references freed, %d things really freed,\n"    "| space for %u gc frames used\n",    cycle_checked, last_cycle, weak_freed,    obj_count - num_objects, max_gc_frames));    }    +  if (gc_ext_weak_refs) { +  size_t to_free = gc_ext_weak_refs;   #ifdef PIKE_DEBUG -  +  obj_count = num_objects; + #endif +  Pike_in_gc = GC_PASS_ZAP_WEAK; +  /* Zap weak references from external to internal things. That +  * doesn't occur very often; only when something have both +  * external weak refs and nonweak cyclic refs from internal +  * things. */ +  gc_zap_ext_weak_refs_in_mappings(); +  gc_zap_ext_weak_refs_in_arrays(); +  /* Multisets handled as arrays. */ +  gc_zap_ext_weak_refs_in_objects(); +  gc_zap_ext_weak_refs_in_programs(); +  GC_VERBOSE_DO( +  fprintf(stderr, +  "| zap weak: freed %ld external weak refs, %lu internal still around,\n" +  "| %d things really freed\n", +  PTRDIFF_T_TO_LONG(to_free - gc_ext_weak_refs), +  SIZE_T_TO_ULONG(gc_ext_weak_refs), obj_count - num_objects)); +  } +  + #ifdef PIKE_DEBUG    if (gc_debug) {    unsigned n;    size_t i;    struct marker *m;    Pike_in_gc=GC_PASS_MIDDLETOUCH;    n = gc_touch_all_arrays();    n += gc_touch_all_multisets();    n += gc_touch_all_mappings();    n += gc_touch_all_programs();    n += gc_touch_all_objects();
pike.git/src/gc.c:2235: Inside #if defined(PIKE_DEBUG), #if 0 /* Temporarily disabled - Hubbe */ and #if defined(DEBUG_MALLOC)
   describe(m->data);    Pike_in_gc = GC_PASS_MIDDLETOUCH;    fatal("Fatal in garbage collector.\n");    }   #endif   #endif    GC_VERBOSE_DO(fprintf(stderr, "| middletouch\n"));    }   #endif    -  if (gc_ext_weak_refs) { -  size_t to_free = gc_ext_weak_refs; - #ifdef PIKE_DEBUG -  obj_count = num_objects; - #endif -  Pike_in_gc = GC_PASS_ZAP_WEAK; -  /* Zap weak references from external to internal things. That -  * doesn't occur very often; only when something have both -  * external weak refs and nonweak cyclic refs from internal -  * things. */ -  gc_zap_ext_weak_refs_in_mappings(); -  gc_zap_ext_weak_refs_in_arrays(); -  /* Multisets handled as arrays. */ -  gc_zap_ext_weak_refs_in_objects(); -  gc_zap_ext_weak_refs_in_programs(); -  GC_VERBOSE_DO( -  fprintf(stderr, -  "| zap weak: freed %ld external weak refs, %lu internal still around,\n" -  "| %d things really freed\n", -  PTRDIFF_T_TO_LONG(to_free - gc_ext_weak_refs), -  SIZE_T_TO_ULONG(gc_ext_weak_refs), obj_count - num_objects)); -  } -  +     /* Add an extra reference to the stuff gc_internal_* point to, so we    * know they're still around when gc_free_all_unreferenced_* are    * about to be called. */    if (gc_internal_array != &weak_empty_array) add_ref(gc_internal_array);    if (gc_internal_multiset) add_ref(gc_internal_multiset);    if (gc_internal_mapping) add_ref(gc_internal_mapping);    if (gc_internal_program) add_ref(gc_internal_program);    if (gc_internal_object) add_ref(gc_internal_object);       /* Thread switches, object alloc/free and reference changes are