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.345 2010/04/19 13:51:48 mast Exp $ + || $Id: gc.c,v 1.346 2010/04/19 14:01:36 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:1696:   {    fprintf(stderr, "## Watched thing %p with %d refs found in "    "%s in pass %d.\n", m->data, *(INT32 *) m->data, found_in, Pike_in_gc);    describe_marker (m);   }      #endif /* PIKE_DEBUG */      #ifndef GC_MARK_DEBUG   struct pike_queue gc_mark_queue; + #define CHECK_MARK_QUEUE_EMPTY() assert (!gc_mark_queue.first)   #else /* GC_MARK_DEBUG */      /* Cut'n'paste from queue.c. */      struct gc_queue_entry   {    queue_call call;    void *data;    int in_type;    void *in;
pike.git/src/gc.c:1720:      struct gc_queue_block   {    struct gc_queue_block *next;    int used;    struct gc_queue_entry entries[GC_QUEUE_ENTRIES];   };      struct gc_queue_block *gc_mark_first = NULL, *gc_mark_last = NULL;    + #define CHECK_MARK_QUEUE_EMPTY() assert (!gc_mark_first) +    void gc_mark_run_queue()   {    struct gc_queue_block *b;       while((b=gc_mark_first))    {    int e;    for(e=0;e<b->used;e++)    {    debug_malloc_touch(b->entries[e].data);
pike.git/src/gc.c:1756:    b = next;    }    gc_mark_first = gc_mark_last = 0;   }      void gc_mark_enqueue (queue_call call, void *data)   {    struct gc_queue_block *b;      #ifdef PIKE_DEBUG +  if (Pike_in_gc != GC_PASS_MARK && Pike_in_gc != GC_PASS_ZAP_WEAK) +  gc_fatal (data, 0, "gc_mark_enqueue() called in invalid gc pass.\n");    if (gc_found_in_type == PIKE_T_UNKNOWN || !gc_found_in)    gc_fatal (data, 0, "gc_mark_enqueue() called outside GC_ENTER.\n");    {    struct marker *m;    if (gc_is_watching && (m = find_marker(data)) && m->flags & GC_WATCHED) {    /* This is useful to set breakpoints on. */    gc_watched_found (m, "gc_mark_enqueue()");    }    }   #endif
pike.git/src/gc.c:3550:       if (gc_destruct_everything) {    GC_VERBOSE_DO(fprintf(stderr,    "| mark pass skipped - will destruct all objects\n"));    }    else {    /* Next we mark anything with external references. Note that we can    * follow the same reference several times, e.g. with shared mapping    * data blocks. */    ACCEPT_UNFINISHED_TYPE_FIELDS { -  /* The queue should be empty here. */ - #ifdef GC_MARK_DEBUG -  assert (!gc_mark_first); - #else -  assert (!gc_mark_queue.first); - #endif -  +  CHECK_MARK_QUEUE_EMPTY();    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();   #ifdef PIKE_DEBUG    if(gc_debug) gc_mark_all_strings();   #endif /* PIKE_DEBUG */ -  +  CHECK_MARK_QUEUE_EMPTY();    } 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:3628:    if (link_frames) fatal ("Leaked %u link frames.\n", link_frames);   #endif    }       if (gc_ext_weak_refs) {    size_t to_free = gc_ext_weak_refs;   #ifdef PIKE_DEBUG    obj_count = delayed_freed;   #endif    Pike_in_gc = GC_PASS_ZAP_WEAK; +  CHECK_MARK_QUEUE_EMPTY();    /* Zap weak references from external to internal things. That    * occurs when something has 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();    gc_zap_ext_weak_refs_in_multisets();    gc_zap_ext_weak_refs_in_objects();    gc_zap_ext_weak_refs_in_programs(); -  +  CHECK_MARK_QUEUE_EMPTY();    GC_VERBOSE_DO(    fprintf(stderr,    "| zap weak: freed %"PRINTPTRDIFFT"d external weak refs, "    "%"PRINTSIZET"u internal still around,\n"    "| %d more things to free\n",    to_free - gc_ext_weak_refs, gc_ext_weak_refs,    delayed_freed - obj_count));    }       if (gc_debug) {