pike.git / src / gc.c

version» Context lines:

pike.git/src/gc.c:1:   /*   || 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.282 2007/05/13 15:42:06 mast Exp $ + || $Id: gc.c,v 1.283 2007/05/13 19:09:57 mast Exp $   */      #include "global.h"      struct callback *gc_evaluator_callback=0;      #include "array.h"   #include "multiset.h"   #include "mapping.h"   #include "object.h"
pike.git/src/gc.c:1664:   #endif    )))    gc_fatal(a, 1, "Thing got an existing but untouched marker.\n");    m = get_marker(a);    m->flags |= GC_PRETOUCHED;   #ifdef PIKE_DEBUG    m->saved_refs = *(INT32 *) a;   #endif    break;    -  case GC_PASS_MIDDLETOUCH: { +  case GC_PASS_POSTTOUCH: {   #ifdef PIKE_DEBUG    int extra_ref;   #endif    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");    if (gc_destruct_everything && (m->flags & GC_MARKED))    gc_fatal (a, 1, "Thing got marked in gc_destruct_everything mode.\n");
pike.git/src/gc.c:1687: Inside #if defined(PIKE_DEBUG)
   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");   #endif -  m->flags |= GC_MIDDLETOUCHED; +  m->flags |= GC_POSTTOUCHED;    break;    }    - #if 0 -  /* Disabled since we can't assume any correlation between the -  * marks and the actual blocks in or after GC_PASS_FREE. */ -  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"); - #ifdef PIKE_DEBUG -  else if (m->flags & GC_MARKED) -  return; -  else if (gc_destruct_everything) -  return; -  else if (!(m->flags & GC_NOT_REFERENCED) || m->flags & GC_XREFERENCED) -  gc_fatal(a, 3, "A thing with external references " -  "got missed by mark pass.\n"); -  else if (!(m->flags & GC_CYCLE_CHECKED)) -  gc_fatal(a, 2, "A thing was missed by " -  "both mark and cycle check pass.\n"); -  else if (!(m->flags & GC_IS_REFERENCED)) -  gc_fatal(a, 2, "An unreferenced thing " -  "got missed by gc_is_referenced().\n"); -  else if (!(m->flags & GC_DO_FREE)) -  gc_fatal(a, 2, "An unreferenced thing " -  "got missed by gc_do_free().\n"); -  else if (m->flags & GC_GOT_EXTRA_REF) -  gc_fatal(a, 2, "A thing still got an extra ref.\n"); -  else if (m->weak_refs > m->saved_refs) -  gc_fatal(a, 2, "A thing got more weak references than references.\n"); -  else if (!(m->flags & GC_LIVE)) { -  if (m->weak_refs < 0) -  gc_fatal(a, 3, "A thing which had only weak references is " -  "still around after gc.\n"); -  else -  gc_fatal(a, 3, "A thing to garb is still around.\n"); -  } - #endif -  } -  break; - #endif -  +     default:    Pike_fatal("debug_gc_touch() used in invalid gc pass.\n");    }   }      #ifdef PIKE_DEBUG      static INLINE struct marker *gc_check_debug(void *a, int weak)   {    struct marker *m;
pike.git/src/gc.c:3287:    gc_mark_all_arrays();    gc_mark_run_queue();    gc_mark_all_multisets();    gc_mark_run_queue();    gc_mark_all_mappings();    gc_mark_run_queue();    gc_mark_all_programs();    gc_mark_run_queue();    gc_mark_all_objects();    gc_mark_run_queue(); - #if 0 - #ifdef DEBUG_MALLOC -  gc_mark_all_types(); - #endif /* DEBUG_MALLOC */ - #endif +    #ifdef PIKE_DEBUG    if(gc_debug) gc_mark_all_strings();   #endif /* PIKE_DEBUG */    } END_ACCEPT_UNFINISHED_TYPE_FIELDS;       GC_VERBOSE_DO(fprintf(stderr,    "| mark: %u markers referenced, %u weak references freed,\n"    "| %d things to free, "    "got %"PRINTSIZET"u tricky weak refs\n",    marked, weak_freed, delayed_freed, gc_ext_weak_refs));
pike.git/src/gc.c:3322:    * follow the same reference several times, just like in the mark    * pass. */    /* Note: The order between types here is normally not significant,    * but the permuting destruct order tests in the testsuite won't be    * really effective unless objects are handled first. :P */    gc_cycle_check_all_objects();    gc_cycle_check_all_arrays();    gc_cycle_check_all_multisets();    gc_cycle_check_all_mappings();    gc_cycle_check_all_programs(); - #if 0 - #ifdef DEBUG_MALLOC -  gc_cycle_check_all_types(); - #endif - #endif +       #ifdef PIKE_DEBUG    if (stack_top != &sentinel_frame)    Pike_fatal("Frame stack not empty at end of cycle check pass.\n");    if (gc_ext_weak_refs != orig_ext_weak_refs)    Pike_fatal("gc_ext_weak_refs changed from %"PRINTSIZET"u "    "to %"PRINTSIZET"u in cycle check pass.\n",    orig_ext_weak_refs, gc_ext_weak_refs);   #endif   
pike.git/src/gc.c:3381:    to_free - gc_ext_weak_refs, gc_ext_weak_refs,    delayed_freed - obj_count));    }       if (gc_debug) {    unsigned n;   #ifdef DEBUG_MALLOC    size_t i;    struct marker *m;   #endif -  Pike_in_gc=GC_PASS_MIDDLETOUCH; +  Pike_in_gc=GC_PASS_POSTTOUCH;    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();   #ifdef PIKE_DEBUG - #if 0 -  gc_touch_all_types(); - #endif +     gc_touch_all_strings();   #endif    if (n != (unsigned) num_objects)    Pike_fatal("Object count wrong in gc; expected %d, got %d.\n", num_objects, n);   #if 0 /* Temporarily disabled - Hubbe */   #ifdef PIKE_DEBUG   #ifdef DEBUG_MALLOC    PTR_HASH_LOOP(marker, i, m) -  if (!(m->flags & (GC_MIDDLETOUCHED|GC_WEAK_FREED)) && +  if (!(m->flags & (GC_POSTTOUCHED|GC_WEAK_FREED)) &&    dmalloc_is_invalid_memory_block(m->data)) { -  fprintf(stderr, "Found a stray marker after middletouch pass: "); +  fprintf(stderr, "Found a stray marker after posttouch pass: ");    describe_marker(m);    fprintf(stderr, "Describing marker location(s):\n");    debug_malloc_dump_references(m, 2, 1, 0);    fprintf(stderr, "Describing thing for marker:\n");    Pike_in_gc = 0;    describe(m->data); -  Pike_in_gc = GC_PASS_MIDDLETOUCH; +  Pike_in_gc = GC_PASS_POSTTOUCH;    Pike_fatal("Fatal in garbage collector.\n");    }   #endif   #endif   #endif -  GC_VERBOSE_DO(fprintf(stderr, "| middletouch\n")); +  GC_VERBOSE_DO(fprintf(stderr, "| posttouch\n"));    }       /* Object alloc/free and reference changes are allowed again now. */       Pike_in_gc=GC_PASS_FREE;   #ifdef PIKE_DEBUG    weak_freed = 0;    obj_count = num_objects;   #endif   
pike.git/src/gc.c:3446:    unreferenced += gc_free_all_unreferenced_objects();    /* Note: gc_free_all_unreferenced_objects needs to have the programs    * around to handle the free (even when they aren't live). So it's    * necessary to free the objects before the programs. */    if (gc_internal_program)    unreferenced += gc_free_all_unreferenced_programs();       if (free_extra_frames > tot_max_free_extra_frames)    tot_max_free_extra_frames = free_extra_frames;    - #if 0 - #ifdef DEBUG_MALLOC -  unreferenced += gc_free_all_unreferenced_types(); - #endif - #endif -  +     /* 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 free_extra_frame *next = free_extra_list->next;    union anything u;    u.refs = (INT32 *) free_extra_list->data;    gc_free_extra_ref (u.refs);    free_short_svalue (&u, free_extra_list->type);    really_free_free_extra_frame (free_extra_list);    free_extra_list = next;
pike.git/src/gc.c:3564:    "%"PRINTSIZET"u things really freed\n",    destroy_count, pre_kill_objs - num_objects));       Pike_in_gc=GC_PASS_DESTRUCT;    /* Destruct objects on the destruct queue. */    GC_VERBOSE_DO(obj_count = num_objects);    destruct_objects_to_destruct();    GC_VERBOSE_DO(fprintf(stderr, "| destruct: %d things really freed\n",    obj_count - num_objects));    - #if 0 -  /* Disabled since we can't assume any correlation between the -  * marks and the actual blocks in or after GC_PASS_FREE. */ -  if (gc_debug) { -  unsigned n; -  Pike_in_gc=GC_PASS_POSTTOUCH; -  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(); -  /* gc_touch_all_types(); */ -  /* gc_touch_all_strings(); */ -  if (n != (unsigned) num_objects) -  Pike_fatal("Object count wrong after gc; expected %d, got %d.\n", num_objects, n); -  GC_VERBOSE_DO(fprintf(stderr, "| posttouch: %u things\n", n)); -  } - #endif -  +    #ifdef PIKE_DEBUG    if (gc_extra_refs) {    size_t e;    fprintf (stderr, "Lost track of %d extra refs to things in gc.\n"    "Searching for marker(s) with extra refs:\n", gc_extra_refs);    for (e = 0; e < marker_hash_table_size; e++) {    struct marker *s = marker_hash_table[e], *m;    for (m = s; m;) {    if (m->flags & GC_GOT_EXTRA_REF) {    fprintf (stderr, "========================================\n"
pike.git/src/gc.c:3613: Inside #if defined(PIKE_DEBUG)
   if (m == s) break;    }    }    fprintf (stderr, "========================================\n"    "Done searching for marker(s) with extra refs.\n");    Pike_fatal("Lost track of %d extra refs to things in gc.\n", gc_extra_refs);    }    if(fatal_after_gc) Pike_fatal("%s", fatal_after_gc);   #endif    -  Pike_in_gc=0; -  exit_gc(); -  +     /* Calculate the next alloc_threshold. */    {    double multiplier, new_threshold;    cpu_time_t last_non_gc_time, last_gc_time;       /* If we're at an automatic and timely gc then start_allocs ==    * alloc_threshold and we're using gc_average_slowness in the    * decaying average calculation. Otherwise this is either an    * explicit call (start_allocs < alloc_threshold) or the gc has    * been delayed past its due time (start_allocs >
pike.git/src/gc.c:3735: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    UNSET_ONERROR (uwp);    tot_cycle_checked += cycle_checked;    tot_mark_live += mark_live, tot_frame_rot += frame_rot;   #endif    if (max_rec_frames > tot_max_rec_frames)    tot_max_rec_frames = max_rec_frames;    if (max_link_frames > tot_max_link_frames)    tot_max_link_frames = max_link_frames;    +  Pike_in_gc=0; +  exit_gc(); +    #ifdef ALWAYS_GC    ADD_GC_CALLBACK();   #else    if(d_flag > 3) ADD_GC_CALLBACK();   #endif      #ifdef DO_PIKE_CLEANUP    if (gc_destruct_everything)    return destroy_count;   #endif