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.314 2008/05/11 16:57:37 mast Exp $ + || $Id: gc.c,v 1.315 2008/05/13 19:03:59 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:154:    union {    struct link_frame *link_top;/* The top of the link stack for frames on the    * recursion stack. */    struct gc_rec_frame *last_cycle_piece;/* In the first frame on a cycle    * piece list, this is used to point to the    * last frame in the list. */    } u;   };      /* rf_flags bits. */ - #define GC_PREV_WEAK 0x01 - #define GC_PREV_STRONG 0x02 - #define GC_PREV_BROKEN 0x04 - #define GC_MARK_LIVE 0x08 - #define GC_ON_KILL_LIST 0x10 + #define GC_PREV_WEAK 0x0001 + #define GC_PREV_STRONG 0x0002 + #define GC_PREV_BROKEN 0x0004 + #define GC_MARK_LIVE 0x0008 + #define GC_ON_KILL_LIST 0x0010   #ifdef PIKE_DEBUG - #define GC_ON_CYCLE_PIECE_LIST 0x20 - #define GC_FRAME_FREED 0x40 - #define GC_FOLLOWED_NONSTRONG 0x80 + #define GC_ON_CYCLE_PIECE_LIST 0x0020 + #define GC_FRAME_FREED 0x0040 + #define GC_FOLLOWED_NONSTRONG 0x0080 + #define GC_IS_VALID_CP_CYCLE_ID 0x0100   #endif      static struct gc_rec_frame sentinel_frame = {    (void *) (ptrdiff_t) -1,    0,    (struct gc_rec_frame *) (ptrdiff_t) -1,    (struct gc_rec_frame *) (ptrdiff_t) -1,    &sentinel_frame, /* Recognize as cycle id frame. */    (struct gc_rec_frame *) (ptrdiff_t) -1,    {(struct link_frame *) (ptrdiff_t) -1}
pike.git/src/gc.c:557: Inside #if defined (PIKE_DEBUG) || defined (GC_CYCLE_DEBUG)
   f->data, f->rf_flags, f->prev, f->next,    f->cycle_id, f->cycle_piece, f->u.link_top);   }      /* If p* isn't NULL then p*_name will be written out next to the    * matching frame in the stack, if any is found. */   static void describe_rec_stack (struct gc_rec_frame *p1, const char *p1_name,    struct gc_rec_frame *p2, const char *p2_name,    struct gc_rec_frame *p3, const char *p3_name)   { -  struct gc_rec_frame *l; +  struct gc_rec_frame *l, *cp;    size_t longest; -  +     if (p1) longest = strlen (p1_name);    if (p2) {size_t l = strlen (p2_name); if (l > longest) longest = l;}    if (p3) {size_t l = strlen (p3_name); if (l > longest) longest = l;}    longest++; -  +  +  /* Note: Stack is listed from top to bottom, but cycle piece lists +  * are lists from first to last, i.e. reverse order. */ +     for (l = stack_top; l != &sentinel_frame; l = l->prev) {    size_t c = 0; -  +     if (!l) {fputs (" <broken prev link in rec stack>\n", stderr); break;}    fprintf (stderr, " %p", l); -  +     if (l == p1) {fprintf (stderr, " %s", p1_name); c += strlen (p1_name) + 1;}    if (l == p2) {fprintf (stderr, " %s", p2_name); c += strlen (p2_name) + 1;}    if (l == p3) {fprintf (stderr, " %s", p3_name); c += strlen (p3_name) + 1;}    fprintf (stderr, ": %*s", c < longest ? (int) (longest - c) : 0, ""); -  +     describe_rec_frame (l);    fputc ('\n', stderr); -  +  +  for (cp = l->cycle_piece; cp; cp = cp->cycle_piece) { +  fprintf (stderr, " %p", cp); +  +  c = 0; +  if (cp == p1) {fprintf (stderr, " %s", p1_name); c += strlen (p1_name)+1;} +  if (cp == p2) {fprintf (stderr, " %s", p2_name); c += strlen (p2_name)+1;} +  if (cp == p3) {fprintf (stderr, " %s", p3_name); c += strlen (p3_name)+1;} +  fprintf (stderr, ": %*s", c < longest ? (int) (longest - c) : 0, ""); +  +  describe_rec_frame (cp); +  fputc ('\n', stderr);    }    } -  + }      #endif      #ifdef PIKE_DEBUG      int gc_in_cycle_check = 0;      static int gc_is_watching = 0;      int attempt_to_identify(void *something, void **inblock)
pike.git/src/gc.c:2239:    l = l->next;    check_rec_stack_frame (l, p1, p1n, p2, p2n, file, line);    if (l->cycle_id == l)    last_cycle_id = l;    else if (l->cycle_id != last_cycle_id)    rec_stack_fatal (l, "err", p1, p1n, p2, p2n, file, line,    "Unexpected cycle id for frame %p.\n", l);    else if (l->rf_flags & GC_PREV_WEAK)    rec_stack_fatal (l, "err", p1, p1n, p2, p2n, file, line,    "Unexpected weak ref before %p inside a cycle.\n", l); +  +  if (l->rf_flags & GC_IS_VALID_CP_CYCLE_ID) +  rec_stack_fatal (l, "err", p1, p1n, p2, p2n, file, line, +  "Frame %p got stray " +  "GC_IS_VALID_CP_CYCLE_ID flag.\n", l); +  if (l->cycle_piece) { +  struct gc_rec_frame *cp = l->cycle_piece; +  l->rf_flags |= GC_IS_VALID_CP_CYCLE_ID; +  +  while (1) { +  if (!cp->cycle_id || +  !(cp->cycle_id->rf_flags & GC_IS_VALID_CP_CYCLE_ID)) +  rec_stack_fatal (cp, "err", p1, p1n, p2, p2n, file, line, +  "Unexpected cycle id for frame %p " +  "on cycle piece list.\n", cp); +  if (cp->rf_flags & GC_IS_VALID_CP_CYCLE_ID) +  rec_stack_fatal (cp, "err", p1, p1n, p2, p2n, file, line, +  "Frame %p got stray " +  "GC_IS_VALID_CP_CYCLE_ID flag.\n", cp); +  cp->rf_flags |= GC_IS_VALID_CP_CYCLE_ID; +  check_cycle_piece_frame (cp, file, line); +  if (!cp->cycle_piece) break; +  cp = cp->cycle_piece;    } -  +  +  if (l->cycle_piece->u.last_cycle_piece != cp) +  rec_stack_fatal (l->cycle_piece, "err", p1, p1n, p2, p2n, file, line, +  "last_cycle_piece is wrong for frame %p, " +  "expected %p.\n", l->cycle_piece, cp); +  +  l->rf_flags &= ~GC_IS_VALID_CP_CYCLE_ID; +  cp = l->cycle_piece; +  do { +  cp->rf_flags &= ~GC_IS_VALID_CP_CYCLE_ID; +  cp = cp->cycle_piece; +  } while (cp);    }    } -  +  } + }   #define CHECK_REC_STACK(p1, p1n, p2, p2n) \    do check_rec_stack ((p1), (p1n), (p2), (p2n), __FILE__, __LINE__); while (0)      #else /* !PIKE_DEBUG */   #define CHECK_REC_STACK_FRAME(f) do {} while (0)   #define CHECK_CYCLE_PIECE_FRAME(f) do {} while (0)   #define CHECK_KILL_LIST_FRAME(f) do {} while (0)   #define CHECK_REC_STACK(p1, p1n, p2, p2n) do {} while (0)   #endif /* !PIKE_DEBUG */