Ejemplo n.º 1
0
static int BTC_ephemeron_mark(void *p, struct NewGC *gc)
{
  if (gc->doing_memory_accounting) {

    GC_Ephemeron *eph = (GC_Ephemeron *)p;

    gcMARK2(eph->key, gc);
    gcMARK2(eph->val, gc);

    return gcBYTES_TO_WORDS(sizeof(GC_Ephemeron));
  }
  return mark_ephemeron(p, gc);
}
Ejemplo n.º 2
0
static int mark_ready_ephemerons(GCTYPE *gc, int inc_gen1)
{
  GC_Ephemeron *waiting, *next, *eph;
  int did_one = 0, j;

  GC_mark_no_recur(gc, 1);

  for (j = 0; j < (inc_gen1 ? 1 : 2); j++) {
    if (inc_gen1)
      eph = gc->inc_ephemerons;
    else if (j == 0)
      eph = gc->ephemerons;
    else
      eph = gc->bp_ephemerons;

    waiting = NULL;
    
    for (; eph; eph = next) {
      if (inc_gen1)
        next = eph->inc_next;
      else
        next = eph->next;
      if (is_marked(gc, eph->key)) {
        if (!inc_gen1)
          eph->key = GC_resolve2(eph->key, gc);
        gcMARK2(eph->val, gc);
        gc->num_last_seen_ephemerons++;
        did_one = 1;
        if (!inc_gen1 && (j == 0) && !gc->gc_full && gc->started_incremental) {
          /* Need to preserve the ephemeron in the incremental list,
             unless it's kept in generation 1/2 nistead of promoted to
             generation 1. */
          if (!is_in_generation_half(gc, eph)) {
            eph->inc_next = gc->inc_ephemerons;
            gc->inc_ephemerons = eph;
          }
        }
      } else {
        if (inc_gen1) {
          /* Ensure that we can write to the page containing the emphemeron: */
          check_incremental_unprotect(gc, pagemap_find_page(gc->page_maps, eph));
          eph->inc_next = waiting;
        } else
          eph->next = waiting;
        waiting = eph;
      }
    }

    if (inc_gen1)
      gc->inc_ephemerons = waiting;
    else if (j == 0)
      gc->ephemerons = waiting;
    else
      gc->bp_ephemerons = waiting;
  }

  GC_mark_no_recur(gc, 0);

  return did_one;
}
Ejemplo n.º 3
0
static int mark_weak_array(void *p, struct NewGC *gc)
{
  GC_Weak_Array *a = (GC_Weak_Array *)p;

  gcMARK2(a->replace_val, gc);

  a->next = gc->weak_arrays;
  gc->weak_arrays = a;

#if CHECKS
  /* For now, weak arrays only used for symbols, keywords, and falses: */
  {
    void **data;
    int i;
    data = a->data;
    for (i = a->count; i--; ) {
      if (data[i] 
	  && (*(short *)(data[i]) != 48)
	  && (*(short *)(data[i]) != 49)
	  && (*(short *)(data[i]) != 58)) {
	CRASH(1);
      }
    }
  }
#endif

  return gcBYTES_TO_WORDS(sizeof(GC_Weak_Array) 
			  + ((a->count - 1) * sizeof(void *)));
}
Ejemplo n.º 4
0
static void MARK_jmpup(Scheme_Jumpup_Buf *buf, struct NewGC *gc)
{
  gcMARK2(buf->stack_copy, gc);
  gcMARK2(buf->cont, gc);
  gcMARK2(buf->external_stack, gc);

  /* IMPORTANT: the buf->stack_copy pointer must be the only instance
     of this stack to be traversed. If you copy a jmpup buffer (as in
     fun.c), don't let a GC happen until the old copy is zeroed
     out. */
  if (buf->stack_copy)
    GC_mark2_variable_stack(buf->gc_var_stack,
                            (intptr_t)buf->stack_copy - (intptr_t)buf->stack_from,
                            /* FIXME: stack direction */
                            (char *)buf->stack_copy + buf->stack_size,
                            buf->stack_copy,
                            gc);
}
Ejemplo n.º 5
0
static int mark_weak_array(void *p, struct NewGC *gc)
{
  GC_Weak_Array *a = (GC_Weak_Array *)p;

  gcMARK2(a->replace_val, gc);

  if (gc->doing_memory_accounting) {
    /* skip */
  } else if (gc->inc_gen1) {
    /* inc_next field is at the end of the `data` array: */
    a->data[a->count] = gc->inc_weak_arrays;
    gc->inc_weak_arrays = a;
  } else if (gc->during_backpointer) {
    if (!gc->gc_full
        || (gc->started_incremental
            /* `a` must have been marked and must be in the old
               generation, or we wouldn't get here; `a` may have been
               fully processed in incremental mode, though */
            && (a->data[a->count] == gc->weak_incremental_done))) {
      /* Keep backpointered weak arrays separate, because we
         should not merge them to the incremental list
         in incremental mode. */
      a->next = gc->bp_weak_arrays;
      gc->bp_weak_arrays = a;
    }
  } else {
    a->next = gc->weak_arrays;
    gc->weak_arrays = a;
    if (gc->gc_full)
      a->data[a->count] = NULL; /* ensure not a future weak_incremental_done */
  }

#if CHECKS
  /* For now, weak arrays only used for symbols, keywords, and falses: */
  {
    void **data;
    int i;
    data = a->data;
    for (i = a->count; i--; ) {
      if (data[i] 
	  && (*(short *)(data[i]) != 48)
	  && (*(short *)(data[i]) != 49)
	  && (*(short *)(data[i]) != 58)) {
	CRASH(1);
      }
    }
  }
#endif

  return gcBYTES_TO_WORDS(sizeof(GC_Weak_Array) 
			  + ((a->count - 1 + 1) * sizeof(void *)));
}
Ejemplo n.º 6
0
static int mark_weak_box(void *p, struct NewGC *gc)
{
  GC_Weak_Box *wb = (GC_Weak_Box *)p;
    
  gcMARK2(wb->secondary_erase, gc);

  if (wb->val) {
    wb->next = gc->weak_boxes[wb->is_late];
    gc->weak_boxes[wb->is_late] = wb;
  }

  return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box));
}
Ejemplo n.º 7
0
static int shape_mark(void *p, struct NewGC *gc) {
#ifndef GC_NO_MARK_PROCEDURE_NEEDED
  intptr_t *shape_str = shape_strs[*(Scheme_Type *)p];

  while (*shape_str != SCHEME_GC_SHAPE_TERM) {
    if (shape_str[0] == SCHEME_GC_SHAPE_PTR_OFFSET) {
      gcMARK2(*(void **)((char *)p + shape_str[1]), gc);
    }
    shape_str += 2;
  }

# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS
  return 0;
# else
  return shape_size(p, gc);
# endif
#endif
}
Ejemplo n.º 8
0
static int mark_ready_ephemerons(GCTYPE *gc)
{
  GC_Ephemeron *waiting = NULL, *next, *eph;
  int did_one = 0;

  for (eph = gc->ephemerons; eph; eph = next) {
    next = eph->next;
    if (is_marked(gc, eph->key)) {
      gcMARK2(eph->val, gc);
      gc->num_last_seen_ephemerons++;
      did_one = 1;
    } else {
      eph->next = waiting;
      waiting = eph;
    }
  }
  gc->ephemerons = waiting;

  return did_one;
}
Ejemplo n.º 9
0
static int mark_weak_box(void *p, struct NewGC *gc)
{
  GC_Weak_Box *wb = (GC_Weak_Box *)p;

  gcMARK2(wb->secondary_erase, gc);

  if (gc->doing_memory_accounting) {
    /* skip */
  } else if (gc->inc_gen1) {
    check_weak_box_not_already_in_inc_chain(wb, gc->inc_weak_boxes[wb->is_late]);
    wb->inc_next = gc->inc_weak_boxes[wb->is_late];
    gc->inc_weak_boxes[wb->is_late] = wb;
  } else if (gc->during_backpointer) {
    if ((!gc->gc_full
         || (gc->started_incremental
             /* see note with `gc->weak_incremental_done` for weak arrays */
             && (wb->inc_next == gc->weak_incremental_done)
             && wb->val))
        && (wb->val || gc->started_incremental)) {
      /* Keep backpointered weak arrays separate, because we
         should not merge them to the incremental list
         in incremental mode. */
      check_weak_box_not_already_in_chain(wb, gc->bp_weak_boxes[wb->is_late]);
      check_weak_box_not_already_in_chain(wb, gc->weak_boxes[wb->is_late]);
      wb->next = gc->bp_weak_boxes[wb->is_late];
      gc->bp_weak_boxes[wb->is_late] = wb;
    }
  } else if (wb->val || gc->started_incremental) {
    check_weak_box_not_already_in_chain(wb, gc->weak_boxes[wb->is_late]);
    check_weak_box_not_already_in_chain(wb, gc->bp_weak_boxes[wb->is_late]);
    wb->next = gc->weak_boxes[wb->is_late];
    gc->weak_boxes[wb->is_late] = wb;
    if (gc->gc_full)
      wb->inc_next = NULL; /* ensure not a future weak_incremental_done */
  }

  return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box));
}
Ejemplo n.º 10
0
static void MARK_cjs(Scheme_Continuation_Jump_State *cjs, struct NewGC *gc)
{
  gcMARK2(cjs->jumping_to_continuation, gc);
  gcMARK2(cjs->alt_full_continuation, gc);
  gcMARK2(cjs->val, gc);
}