pike.git / src / gc.c

version» Context lines:

pike.git/src/gc.c:20:   #include "pike_macros.h"   #include "pike_rusage.h"   #include "pike_types.h"   #include "time_stuff.h"   #include "constants.h"   #include "interpret.h"   #include "bignum.h"   #include "pike_threadlib.h"   #include "gc.h"   #include "main.h" + #include "block_allocator.h"      #include <math.h>      #include "block_alloc.h"      int gc_enabled = 1;      /* These defaults are only guesses and hardly tested at all. Please improve. */   double gc_garbage_ratio_low = 0.2;   double gc_time_ratio = 0.05;
pike.git/src/gc.c:413: Inside #if defined(PIKE_DEBUG)
  static unsigned mark_live, frame_rot, link_search;   static unsigned gc_extra_refs = 0;   static unsigned tot_cycle_checked = 0, tot_mark_live = 0, tot_frame_rot = 0;   static unsigned gc_rec_frame_seq_max;   #endif      static unsigned rec_frames, link_frames, free_extra_frames;   static unsigned max_rec_frames, max_link_frames;   static unsigned tot_max_rec_frames = 0, tot_max_link_frames = 0, tot_max_free_extra_frames = 0;    - #undef INIT_BLOCK - #define INIT_BLOCK(f) do { \ -  if (++rec_frames > max_rec_frames) \ -  max_rec_frames = rec_frames; \ -  } while (0) - #undef EXIT_BLOCK - #define EXIT_BLOCK(f) do { \ -  DO_IF_DEBUG ({ \ -  if (f->rf_flags & GC_FRAME_FREED) \ -  gc_fatal (f->data, 0, "Freeing gc_rec_frame twice.\n"); \ -  f->rf_flags |= GC_FRAME_FREED; \ -  f->u.link_top = (struct link_frame *) (ptrdiff_t) -1; \ -  f->prev = f->next = f->cycle_id = f->cycle_piece = \ -  (struct gc_rec_frame *) (ptrdiff_t) -1; \ -  }); \ -  rec_frames--; \ -  } while (0) + struct block_allocator gc_rec_frame_allocator = +  BA_INIT_PAGES(sizeof(struct gc_rec_frame), 2);    - BLOCK_ALLOC_FILL_PAGES (gc_rec_frame, 2) + static void really_free_gc_rec_frame(struct gc_rec_frame * f) { + #ifdef PIKE_DEBUG +  if (f->rf_flags & GC_FRAME_FREED) +  gc_fatal (f->data, 0, "Freeing gc_rec_frame twice.\n"); +  f->rf_flags |= GC_FRAME_FREED; +  f->u.link_top = (struct link_frame *) (ptrdiff_t) -1; +  f->prev = f->next = f->cycle_id = f->cycle_piece = +  (struct gc_rec_frame *) (ptrdiff_t) -1; + #endif +  rec_frames--; +  ba_free(&gc_rec_frame_allocator, f); + }    -  + void count_memory_in_gc_rec_frames(size_t *num, size_t * size) { +  ba_count_all(&gc_rec_frame_allocator, num, size); + } +    /* Link and free_extra frames are approximately the same size, so let    * them share block_alloc area. */   struct ba_mixed_frame   {    union {    struct link_frame link;    struct free_extra_frame free_extra;    struct ba_mixed_frame *next; /* For block_alloc internals. */    } u;   };    - #undef BLOCK_ALLOC_NEXT - #define BLOCK_ALLOC_NEXT u.next - #undef INIT_BLOCK - #define INIT_BLOCK(f) - #undef EXIT_BLOCK - #define EXIT_BLOCK(f) + static struct block_allocator ba_mixed_frame_allocator +  = BA_INIT_PAGES(sizeof(struct ba_mixed_frame), 2);    - BLOCK_ALLOC_FILL_PAGES (ba_mixed_frame, 2) + void count_memory_in_ba_mixed_frames(size_t *num, size_t * size) { +  ba_count_all(&ba_mixed_frame_allocator, num, size); + }      static INLINE struct link_frame *alloc_link_frame()   { -  struct ba_mixed_frame *f = alloc_ba_mixed_frame(); +  struct ba_mixed_frame *f = ba_alloc(&ba_mixed_frame_allocator);    if (++link_frames > max_link_frames)    max_link_frames = link_frames;    return (struct link_frame *) f;   }      static INLINE struct free_extra_frame *alloc_free_extra_frame()   { -  struct ba_mixed_frame *f = alloc_ba_mixed_frame(); +  struct ba_mixed_frame *f = ba_alloc(&ba_mixed_frame_allocator);    free_extra_frames++;    return (struct free_extra_frame *) f;   }      static INLINE void really_free_link_frame (struct link_frame *f)   {    link_frames--; -  really_free_ba_mixed_frame ((struct ba_mixed_frame *) f); +  ba_free(&ba_mixed_frame_allocator, f);   }      static INLINE void really_free_free_extra_frame (struct free_extra_frame *f)   {    free_extra_frames--; -  really_free_ba_mixed_frame ((struct ba_mixed_frame *) f); +  ba_free(&ba_mixed_frame_allocator, f);   }      /* These are only collected for the sake of gc_status. */   static double last_garbage_ratio = 0.0;   static enum {    GARBAGE_RATIO_LOW, GARBAGE_RATIO_HIGH, GARBAGE_MAX_INTERVAL   } last_garbage_strategy = GARBAGE_RATIO_LOW;      struct callback_list gc_callbacks;   
pike.git/src/gc.c:515:   #ifdef PIKE_DEBUG   #define INIT_BLOCK(X) \    (X)->flags=(X)->refs=(X)->weak_refs=(X)->xrefs=0; \    (X)->saved_refs=-1; \    (X)->frame = 0;   #else   #define INIT_BLOCK(X) \    (X)->flags=(X)->refs=(X)->weak_refs=0; \    (X)->frame = 0;   #endif + #undef EXIT_BLOCK + #define EXIT_BLOCK(f)      #undef get_marker   #define get_marker debug_get_marker   #undef find_marker   #define find_marker debug_find_marker      PTR_HASH_ALLOC_FIXED_FILL_PAGES(marker,2)      #undef get_marker   #define get_marker(X) ((struct marker *) debug_malloc_pass(debug_get_marker(X)))
pike.git/src/gc.c:567: Inside #if defined (PIKE_DEBUG) || defined (GC_CYCLE_DEBUG)
   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, *cp; -  size_t longest; +  size_t longest = 0;       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) {
pike.git/src/gc.c:2032:      void exit_gc(void)   {    if (gc_evaluator_callback) {    remove_callback(gc_evaluator_callback);    gc_evaluator_callback = NULL;    }    if (!gc_keep_markers)    cleanup_markers();    -  free_all_gc_rec_frame_blocks(); -  free_all_ba_mixed_frame_blocks(); +  ba_destroy(&gc_rec_frame_allocator); +  ba_destroy(&ba_mixed_frame_allocator);      #ifdef PIKE_DEBUG    if (gc_is_watching) {    fprintf(stderr, "## Exiting gc and resetting watches for %d things.\n",    gc_is_watching);    gc_is_watching = 0;    }   #endif   }   
pike.git/src/gc.c:2340:   #define CHECK_KILL_LIST_FRAME(f) \    do check_kill_list_frame ((f), __FILE__, __LINE__); while (0)      static void check_rec_stack (struct gc_rec_frame *p1, const char *p1n,    struct gc_rec_frame *p2, const char *p2n,    const char *file, int line)   {    /* This debug check is disabled during the final cleanup since this    * is O(n^2) on the stack size, and the stack gets a lot larger then. */    if (gc_debug && !gc_destruct_everything) { -  struct gc_rec_frame *l, *last_cycle_id; +  struct gc_rec_frame *l, *last_cycle_id = NULL;    for (l = &sentinel_frame; l != stack_top;) {    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,
pike.git/src/gc.c:2629: Inside #if defined(GC_STACK_DEBUG)
  #ifdef GC_STACK_DEBUG    fprintf (stderr, "push link %p [%p in %p]: ", l, stack_top->u.link_top, stack_top);    describe_link_frame (l);    fputc('\n', stderr);   #endif    stack_top->u.link_top = l;   }      static struct gc_rec_frame *gc_cycle_enqueue_rec (void *data)   { -  struct gc_rec_frame *r = alloc_gc_rec_frame(); +  struct gc_rec_frame *r = +  (struct gc_rec_frame*)ba_alloc(&gc_rec_frame_allocator); +  if (++rec_frames > max_rec_frames) max_rec_frames = rec_frames;   #ifdef PIKE_DEBUG    if (Pike_in_gc != GC_PASS_CYCLE)    gc_fatal(data, 0, "Use of the gc frame stack outside the cycle check pass.\n");    r->next = (struct gc_rec_frame *) (ptrdiff_t) -1;   #endif    r->data = data;    r->u.link_top = NULL;    r->prev = stack_top;    r->cycle_id = r;    r->cycle_piece = NULL;