示例#1
0
文件: gc.c 项目: Everysick/mruby
/* Perform a full gc cycle */
MRB_API void
mrb_full_gc(mrb_state *mrb)
{
  mrb_gc *gc = &mrb->gc;

  if (gc->disabled || gc->iterating) return;

  GC_INVOKE_TIME_REPORT("mrb_full_gc()");
  GC_TIME_START;

  if (is_generational(gc)) {
    /* clear all the old objects back to young */
    clear_all_old(mrb, gc);
    gc->full = TRUE;
  }
  else if (gc->state != MRB_GC_STATE_ROOT) {
    /* finish half baked GC cycle */
    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
  }

  incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
  gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio;

  if (is_generational(gc)) {
    gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
    gc->full = FALSE;
  }

  GC_TIME_STOP_AND_REPORT;
}
示例#2
0
文件: gc.c 项目: anehing/mruby
/* Perform a full gc cycle */
void
mrb_full_gc(mrb_state *mrb)
{
  if (mrb->gc_disabled) return;
  GC_INVOKE_TIME_REPORT("mrb_full_gc()");
  GC_TIME_START;

  if (is_generational(mrb)) {
    /* clear all the old objects back to young */
    clear_all_old(mrb);
    mrb->gc_full = TRUE;
  }
  else if (mrb->gc_state != GC_STATE_NONE) {
    /* finish half baked GC cycle */
    incremental_gc_until(mrb, GC_STATE_NONE);
  }

  incremental_gc_until(mrb, GC_STATE_NONE);
  mrb->gc_threshold = (mrb->gc_live_after_mark/100) * mrb->gc_interval_ratio;

  if (is_generational(mrb)) {
    mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
    mrb->gc_full = FALSE;
  }

  GC_TIME_STOP_AND_REPORT;
}
示例#3
0
文件: gc.c 项目: silkycove/mruby
void
mrb_garbage_collect(mrb_state *mrb)
{
  size_t max_limit = ~0;

  if (mrb->gc_disabled) return;
  GC_INVOKE_TIME_REPORT("mrb_garbage_collect()");
  GC_TIME_START;

  if (mrb->gc_state == GC_STATE_SWEEP) {
    /* finish sweep phase */
    while (mrb->gc_state != GC_STATE_NONE) {
      incremental_gc(mrb, max_limit);
    }
  }

  /* clean all black object as old */
  if (is_generational(mrb)) {
    clear_all_old(mrb);
    mrb->gc_full = TRUE;
  }

  do {
    incremental_gc(mrb, max_limit);
  } while (mrb->gc_state != GC_STATE_NONE);

  mrb->gc_threshold = (mrb->gc_live_after_mark/100) * mrb->gc_interval_ratio;

  if (is_generational(mrb)) {
    mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
    mrb->gc_full = FALSE;
  }

  GC_TIME_STOP_AND_REPORT;
}
示例#4
0
文件: gc.c 项目: anehing/mruby
static void
change_gen_gc_mode(mrb_state *mrb, mrb_int enable)
{
  if (is_generational(mrb) && !enable) {
    clear_all_old(mrb);
    mrb_assert(mrb->gc_state == GC_STATE_NONE);
    mrb->gc_full = FALSE;
  }
  else if (!is_generational(mrb) && enable) {
    incremental_gc_until(mrb, GC_STATE_NONE);
    mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
    mrb->gc_full = FALSE;
  }
  mrb->is_generational_gc_mode = enable;
}
示例#5
0
文件: gc.c 项目: TressaOrg/mruby
static void
change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable)
{
  if (is_generational(gc) && !enable) {
    clear_all_old(mrb, gc);
    mrb_assert(gc->state == MRB_GC_STATE_ROOT);
    gc->full = FALSE;
  }
  else if (!is_generational(gc) && enable) {
    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
    gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
    gc->full = FALSE;
  }
  gc->generational = enable;
}
示例#6
0
文件: gc.c 项目: anehing/mruby
void
mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value)
{
  if (!is_black(obj)) return;
  if (!is_white(value)) return;

  mrb_assert(!is_dead(mrb, value) && !is_dead(mrb, obj));
  mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);

  if (is_generational(mrb) || mrb->gc_state == GC_STATE_MARK) {
    add_gray_list(mrb, value);
  }
  else {
    mrb_assert(mrb->gc_state == GC_STATE_SWEEP);
    paint_partial_white(mrb, obj); /* for never write barriers */
  }
}
示例#7
0
文件: gc.c 项目: Everysick/mruby
static void
change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable)
{
  if (gc->disabled || gc->iterating) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "generational mode changed when GC disabled");
    return;
  }
  if (is_generational(gc) && !enable) {
    clear_all_old(mrb, gc);
    mrb_assert(gc->state == MRB_GC_STATE_ROOT);
    gc->full = FALSE;
  }
  else if (!is_generational(gc) && enable) {
    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
    gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
    gc->full = FALSE;
  }
  gc->generational = enable;
}
示例#8
0
文件: gc.c 项目: Everysick/mruby
MRB_API void
mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value)
{
  mrb_gc *gc = &mrb->gc;

  if (!is_black(obj)) return;
  if (!is_white(value)) return;

  mrb_assert(gc->state == MRB_GC_STATE_MARK || (!is_dead(gc, value) && !is_dead(gc, obj)));
  mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT);

  if (is_generational(gc) || gc->state == MRB_GC_STATE_MARK) {
    add_gray_list(mrb, gc, value);
  }
  else {
    mrb_assert(gc->state == MRB_GC_STATE_SWEEP);
    paint_partial_white(gc, obj); /* for never write barriers */
  }
}
示例#9
0
文件: gc.c 项目: anehing/mruby
void
mrb_write_barrier(mrb_state *mrb, struct RBasic *obj)
{
  if (!is_black(obj)) return;

  mrb_assert(!is_dead(mrb, obj));
  mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
  paint_gray(obj);
  obj->gcnext = mrb->atomic_gray_list;
  mrb->atomic_gray_list = obj;
}
示例#10
0
文件: gc.c 项目: Everysick/mruby
MRB_API void
mrb_write_barrier(mrb_state *mrb, struct RBasic *obj)
{
  mrb_gc *gc = &mrb->gc;

  if (!is_black(obj)) return;

  mrb_assert(!is_dead(gc, obj));
  mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT);
  paint_gray(obj);
  obj->gcnext = gc->atomic_gray_list;
  gc->atomic_gray_list = obj;
}
示例#11
0
文件: gc.c 项目: silkycove/mruby
static void
clear_all_old(mrb_state *mrb)
{
  size_t origin_mode = mrb->is_generational_gc_mode;

  gc_assert(is_generational(mrb));
  if (is_major_gc(mrb)) {
    advance_phase(mrb, GC_STATE_NONE);
  }

  mrb->is_generational_gc_mode = FALSE;
  prepare_incremental_sweep(mrb);
  advance_phase(mrb, GC_STATE_NONE);
  mrb->variable_gray_list = mrb->gray_list = NULL;
  mrb->is_generational_gc_mode = origin_mode;
}
示例#12
0
文件: gc.c 项目: anehing/mruby
static void
clear_all_old(mrb_state *mrb)
{
  mrb_bool origin_mode = mrb->is_generational_gc_mode;

  mrb_assert(is_generational(mrb));
  if (is_major_gc(mrb)) {
    /* finish the half baked GC */
    incremental_gc_until(mrb, GC_STATE_NONE);
  }

  /* Sweep the dead objects, then reset all the live objects
   * (including all the old objects, of course) to white. */
  mrb->is_generational_gc_mode = FALSE;
  prepare_incremental_sweep(mrb);
  incremental_gc_until(mrb, GC_STATE_NONE);
  mrb->is_generational_gc_mode = origin_mode;

  /* The gray objects has already been painted as white */
  mrb->atomic_gray_list = mrb->gray_list = NULL;
}
示例#13
0
文件: gc.c 项目: Everysick/mruby
static void
clear_all_old(mrb_state *mrb, mrb_gc *gc)
{
  mrb_bool origin_mode = gc->generational;

  mrb_assert(is_generational(gc));
  if (is_major_gc(gc)) {
    /* finish the half baked GC */
    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
  }

  /* Sweep the dead objects, then reset all the live objects
   * (including all the old objects, of course) to white. */
  gc->generational = FALSE;
  prepare_incremental_sweep(mrb, gc);
  incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
  gc->generational = origin_mode;

  /* The gray objects have already been painted as white */
  gc->atomic_gray_list = gc->gray_list = NULL;
}
示例#14
0
文件: gc.c 项目: anehing/mruby
static size_t
incremental_sweep_phase(mrb_state *mrb, size_t limit)
{
  struct heap_page *page = mrb->sweeps;
  size_t tried_sweep = 0;

  while (page && (tried_sweep < limit)) {
    RVALUE *p = page->objects;
    RVALUE *e = p + MRB_HEAP_PAGE_SIZE;
    size_t freed = 0;
    mrb_bool dead_slot = TRUE;
    int full = (page->freelist == NULL);

    if (is_minor_gc(mrb) && page->old) {
      /* skip a slot which doesn't contain any young object */
      p = e;
      dead_slot = FALSE;
    }
    while (p<e) {
      if (is_dead(mrb, &p->as.basic)) {
        if (p->as.basic.tt != MRB_TT_FREE) {
          obj_free(mrb, &p->as.basic);
          p->as.free.next = page->freelist;
          page->freelist = (struct RBasic*)p;
          freed++;
        }
      }
      else {
        if (!is_generational(mrb))
          paint_partial_white(mrb, &p->as.basic); /* next gc target */
        dead_slot = 0;
      }
      p++;
    }

    /* free dead slot */
    if (dead_slot && freed < MRB_HEAP_PAGE_SIZE) {
      struct heap_page *next = page->next;

      unlink_heap_page(mrb, page);
      unlink_free_heap_page(mrb, page);
      mrb_free(mrb, page);
      page = next;
    }
    else {
      if (full && freed > 0) {
        link_free_heap_page(mrb, page);
      }
      if (page->freelist == NULL && is_minor_gc(mrb))
        page->old = TRUE;
      else
        page->old = FALSE;
      page = page->next;
    }
    tried_sweep += MRB_HEAP_PAGE_SIZE;
    mrb->live -= freed;
    mrb->gc_live_after_mark -= freed;
  }
  mrb->sweeps = page;
  return tried_sweep;
}