Esempio n. 1
0
File: gc.c Progetto: hsk/docs
void gc_mark_object(Object* object) {
    ObjectHeader* head = &((ObjectHeader*)object)[-1];
    debug("mark %p\n",head);
    long size;
    if (!heap_find(vm, head)) {
        debug2("******** unfind in heap %p\n", &head[1]);
        return;
    }
    debug2("find\n");
    if (head->marked) return;
    long* bitmap;
    head->marked = 1;
    switch(head->type) {
    case OBJ_BOXED_ARRAY:
        debug("BOXED_ARRAY\n");
        size = ((int)head->size) / sizeof(long);
        debug2("size=%ld\n",size);
        for(int i = 0; i < size; i++)
            gc_mark_object(object->field[i]);
        debug2("END\n");
        break;
    case OBJ_PAIR:
        debug("PAIR\n");
        gc_mark_object(object->fst);
        gc_mark_object(object->snd);
        break;
    case OBJ_UNBOXED_ARRAY:
        debug("UNBOXED ARRAY\n");
        break;
    case OBJ_VM:
        debug("VM\n");
        break;
    case OBJ_RECORD:
        size = ((int)head->size) / sizeof(long);
        debug("RECORD size=%ld\n", size);
        bitmap = &object->longs[size];
        debug2("size=%ld\n",size);
        for(int i = 0; i < size; i++) {
            if(bitmap[i/sizeof(long)] & (1 << (i % sizeof(long))))
                gc_mark_object(object->field[i]);
            else {
                debug2("skip %d\n", i);
            }
        }
        break;
    }
}
Esempio n. 2
0
void _VMArray_mark_references(void* _self) {
    pVMArray self = (pVMArray)_self;
	int size_of_indexable_fields = SEND(self, get_number_of_indexable_fields);
	for(int i=0;i<size_of_indexable_fields;i++) {
		gc_mark_object(SEND(self, get_indexable_field, i));
	}
	SUPER(VMObject, self, mark_references);
}
Esempio n. 3
0
static void
gc_mark(pic_state *pic, pic_value v)
{
  if (! obj_p(pic, v))
    return;

  gc_mark_object(pic, obj_ptr(pic, v));
}
Esempio n. 4
0
File: gc.c Progetto: hsk/docs
void gc_collect_pipe(Object* data) {
    long prev_num = vm->heap_num;
    gc_mark_object(data);
    gc_sweep(NULL);

    vm->heap_max = prev_num * 2;

    debug("Collected %ld objects, %ld remaining.\n", prev_num - vm->heap_num,
          vm->heap_num);
}
Esempio n. 5
0
static void gc_mark() {
	int i;
    num_live_objects = 0;
	for (i = 0; i < num_roots; i++) {
		if (DEBUG) printf("root[%d]=%p\n", i, _roots[i]);
		Object *p = *_roots[i];
		if (p != NULL) {
			if (gc_in_heap(p)) {
				gc_mark_object(p);
			}
		}
	}
}
Esempio n. 6
0
File: test6.c Progetto: hsk/docs
void gc_mark_frame(Frame *frame, Object** objects) {
  for(int i = 0; i < frame->bitmap_size; i++) {
    unsigned int bitmap = frame->bitmap[i];
    int n = i * 32;
    while (bitmap) {
      if(bitmap & 1) {
        gc_mark_object(objects[n]);
      }
      bitmap = bitmap >> 1;
      n++;
    }
  }  
}
Esempio n. 7
0
File: gc.c Progetto: hsk/docs
Object* gc_collect_end_vm(Object* data, VM* _vm) {
    long prev_num = vm->heap_num;
    debug2("gc mark\n");
    gc_mark_object(data);
    debug2("gc sweep\n");
    gc_sweep(_vm);

    vm->heap_max = prev_num * 2;

    debug("Collected %ld objects, %ld moving.\n", prev_num - vm->heap_num,
          vm->heap_num);
    return data;
}
Esempio n. 8
0
File: test5.c Progetto: hsk/docs
void gc_mark_object(Object* object) {
  ObjectHeader* head = &((ObjectHeader*)object)[-1];
  debug("mark %p\n",head);
  long size;
  if (!heap_find(head)) return;
  if (head->marked) return;
  long* bitmap;
  head->marked = 1;
  switch(head->type) {
    case OBJ_BOXED_ARRAY:
      size = ((int)head->size) / sizeof(long);
      debug("size=%ld\n",size);
      for(int i = 0; i < size; i++)
          gc_mark_object(object->field[i]);
      break;
    case OBJ_PAIR:
      debug("PAIR\n");
      gc_mark_object(object->pair.fst);
      gc_mark_object(object->pair.snd);
      break;
    case OBJ_UNBOXED_ARRAY:
      break;
    case OBJ_RECORD:
      size = ((int)head->size) / sizeof(long);
      debug("RECORD size=%ld\n", size);
      bitmap = &object->longs[size];
      debug("size=%ld\n",size);
      for(int i = 0; i < size; i++) {
        if(bitmap[i/sizeof(long)] & (1 << (i % sizeof(long))))
          gc_mark_object(object->field[i]);
        else
          debug("skip %d\n", i);
      }
      break;
  }
}
Esempio n. 9
0
File: gc.c Progetto: hsk/docs
void gc_mark() {
    Frame* frame = frame_list;
    while(frame != frame_bottom) {
        debug2("gc mark %p size %ld\n", frame, frame->frame_size);
        int pos = frame->frame_size;
        if(pos > frame->frame_pos) pos = frame->frame_pos;
        for(int i = 0; i < pos; i++) {
            gc_mark_object(frame->frame_data[i]);
            debug2("done\n");
        }
        debug2("next %p\n", frame);
        debug2("next prev %p %p\n", frame->frame_prev, frame_bottom);
        frame = frame->frame_prev;
    }
    debug2("gc mark done\n");
}
Esempio n. 10
0
File: test5.c Progetto: hsk/docs
void gc_mark_stack_map(int size, Object** objects) {
  for(int i = 0; i < size; i++)
    gc_mark_object(objects[i]);
}
Esempio n. 11
0
void _VMMethod_mark_references(void* _self) {
    pVMMethod self = (pVMMethod) _self;
    gc_mark_object(self->signature);
    gc_mark_object(self->holder); 
	SUPER(VMArray, self, mark_references);
}
Esempio n. 12
0
static void
gc_mark_phase(pic_state *pic)
{
  struct context *cxt;
  size_t j;

  assert(pic->heap->weaks == NULL);

  /* context */
  for (cxt = pic->cxt; cxt != NULL; cxt = cxt->prev) {
    if (cxt->fp) gc_mark_object(pic, (struct object *)cxt->fp);
    if (cxt->sp) gc_mark_object(pic, (struct object *)cxt->sp);
    if (cxt->irep) gc_mark_object(pic, (struct object *)cxt->irep);
  }

  /* arena */
  for (j = 0; j < pic->ai; ++j) {
    gc_mark_object(pic, (struct object *)pic->arena[j]);
  }

  /* global variables */
  gc_mark(pic, pic->globals);

  /* dynamic environment */
  gc_mark(pic, pic->dyn_env);

  /* top continuation */
  gc_mark(pic, pic->halt);

  /* features */
  gc_mark(pic, pic->features);

  /* weak maps */
  do {
    struct object *key;
    pic_value val;
    int it;
    khash_t(weak) *h;
    struct weak *weak;

    j = 0;
    weak = pic->heap->weaks;

    while (weak != NULL) {
      h = &weak->hash;
      for (it = kh_begin(h); it != kh_end(h); ++it) {
        if (! kh_exist(h, it))
          continue;
        key = kh_key(h, it);
        val = kh_val(h, it);
        if (is_alive(key)) {
          if (obj_p(pic, val) && ! is_alive(obj_ptr(pic, val))) {
            gc_mark(pic, val);
            ++j;
          }
        }
      }
      weak = weak->prev;
    }
  } while (j > 0);
}
Esempio n. 13
0
static void
gc_mark_object(pic_state *pic, struct object *obj)
{
 loop:

  if (is_alive(obj))
    return;

  mark(obj);

#define LOOP(o) obj = (struct object *)(o); goto loop

  switch (obj_type(pic, obj)) {
  case PIC_TYPE_PAIR: {
    gc_mark(pic, obj->u.pair.car);
    if (obj_p(pic, obj->u.pair.cdr)) {
      LOOP(obj_ptr(pic, obj->u.pair.cdr));
    }
    break;
  }
  case PIC_TYPE_FRAME: {
    int i;

    for (i = 0; i < obj->u.frame.regc; ++i) {
      gc_mark(pic, obj->u.frame.regs[i]);
    }
    if (obj->u.frame.up) {
      LOOP(obj->u.frame.up);
    }
    break;
  }
  case PIC_TYPE_PROC_FUNC: {
    if (obj->u.proc.env) {
      LOOP(obj->u.proc.env);
    }
    break;
  }
  case PIC_TYPE_PROC_IREP: {
    if (obj->u.proc.env) {
      gc_mark_object(pic, (struct object *)obj->u.proc.env);
    }
    LOOP(obj->u.proc.u.irep);
    break;
  }
  case PIC_TYPE_IREP: {
    size_t i;
    for (i = 0; i < obj->u.irep.objc; ++i) {
      gc_mark(pic, obj->u.irep.obj[i]);
    }
    for (i = 0; i < obj->u.irep.irepc; ++i) {
      gc_mark_object(pic, (struct object *)obj->u.irep.irep[i]);
    }
    break;
  }
  case PIC_TYPE_PORT: {
    break;
  }
  case PIC_TYPE_ERROR: {
    gc_mark_object(pic, (struct object *)obj->u.err.type);
    gc_mark(pic, obj->u.err.irrs);
    LOOP(obj->u.err.msg);
    break;
  }
  case PIC_TYPE_STRING: {
    break;
  }
  case PIC_TYPE_VECTOR: {
    int i;
    for (i = 0; i < obj->u.vec.len; ++i) {
      gc_mark(pic, obj->u.vec.data[i]);
    }
    break;
  }
  case PIC_TYPE_BLOB: {
    break;
  }
  case PIC_TYPE_DATA: {
    break;
  }
  case PIC_TYPE_DICT: {
    pic_value key, val;
    int it = 0;

    while (pic_dict_next(pic, obj_value(pic, &obj->u.dict), &it, &key, &val)) {
      gc_mark(pic, key);
      gc_mark(pic, val);
    }
    break;
  }
  case PIC_TYPE_RECORD: {
    gc_mark(pic, obj->u.rec.datum);
    LOOP(obj->u.rec.type);
    break;
  }
  case PIC_TYPE_SYMBOL: {
    LOOP(obj->u.sym.str);
    break;
  }
  case PIC_TYPE_WEAK: {
    struct weak *weak = (struct weak *)obj;

    weak->prev = pic->heap->weaks;
    pic->heap->weaks = weak;
    break;
  }
  default:
    PIC_UNREACHABLE();
  }
}
Esempio n. 14
0
void
pic_gc(pic_state *pic)
{
  struct context *cxt;
  size_t j;
  khash_t(oblist) *s = &pic->oblist;
  struct symbol *sym;
  int it;
  struct object *obj, *prev, *next;

  assert(pic->gc_attrs == NULL);

  if (! pic->gc_enable) {
    return;
  }

  /* scan objects */

  for (cxt = pic->cxt; cxt != NULL; cxt = cxt->prev) {
    if (cxt->fp) gc_mark_object(pic, (struct object *)cxt->fp);
    if (cxt->sp) gc_mark_object(pic, (struct object *)cxt->sp);
    if (cxt->irep) gc_mark_object(pic, (struct object *)cxt->irep);
    gc_mark(pic, cxt->conts);
  }

  for (j = 0; j < pic->ai; ++j) {
    gc_mark_object(pic, (struct object *)pic->arena[j]);
  }

  gc_mark(pic, pic->globals);
  gc_mark(pic, pic->halt);

  /* scan weak references */

  do {
    struct object *key;
    pic_value val;
    int it;
    khash_t(attr) *h;
    struct attr *attr;

    j = 0;
    attr = pic->gc_attrs;

    while (attr != NULL) {
      h = &attr->hash;
      for (it = kh_begin(h); it != kh_end(h); ++it) {
        if (! kh_exist(h, it))
          continue;
        key = kh_key(h, it);
        val = kh_val(h, it);
        if (is_alive(key)) {
          if (pic_obj_p(pic, val) && ! is_alive((struct object *) pic_ptr(pic, val))) {
            gc_mark(pic, val);
            ++j;
          }
        }
      }
      attr = attr->prev;
    }
  } while (j > 0);

  /* reclaim dead weak references */

  while (pic->gc_attrs != NULL) {
    khash_t(attr) *h = &pic->gc_attrs->hash;
    for (it = kh_begin(h); it != kh_end(h); ++it) {
      if (! kh_exist(h, it))
        continue;
      obj = kh_key(h, it);
      if (! is_alive(obj)) {
        kh_del(attr, h, it);
      }
    }
    pic->gc_attrs = pic->gc_attrs->prev;
  }

  for (it = kh_begin(s); it != kh_end(s); ++it) {
    if (! kh_exist(s, it))
      continue;
    sym = kh_val(s, it);
    if (sym && ! is_alive((struct object *)sym)) {
      kh_del(oblist, s, it);
    }
  }

  /* reclaim dead objects */

  for (prev = &pic->gc_head, obj = prev->next; obj != &pic->gc_head; prev = obj, obj = next) {
    next = obj->next;
    if (is_alive(obj)) {
      unmark(obj);
    } else {
      gc_finalize_object(pic, obj);
      pic_free(pic, obj);
      prev->next = next;
      obj = prev;
    }
  }
}
Esempio n. 15
0
static void
gc_mark_object(pic_state *pic, struct object *obj)
{
 loop:

  if (is_alive(obj))
    return;

  mark(obj);

#define LOOP(o) obj = (struct object *)(o); goto loop

  switch (obj_type(obj)) {
  case PIC_TYPE_PAIR: {
    struct pair *pair = (struct pair *) obj;
    gc_mark(pic, pair->car);
    if (pic_obj_p(pic, pair->cdr)) {
      LOOP(pic_ptr(pic, pair->cdr));
    }
    break;
  }
  case PIC_TYPE_FRAME: {
    struct frame *frame = (struct frame *) obj;
    int i;
    for (i = 0; i < frame->regc; ++i) {
      gc_mark(pic, frame->regs[i]);
    }
    if (frame->up) {
      LOOP(frame->up);
    }
    break;
  }
  case PIC_TYPE_PROC_FUNC: {
    struct proc *proc = (struct proc *) obj;
    if (proc->env) {
      LOOP(proc->env);
    }
    break;
  }
  case PIC_TYPE_PROC_IREP: {
    struct proc *proc = (struct proc *) obj;
    if (proc->env) {
      gc_mark_object(pic, (struct object *) proc->env);
    }
    LOOP(proc->u.irep);
    break;
  }
  case PIC_TYPE_IREP: {
    struct irep *irep = (struct irep *) obj;
    size_t i;
    for (i = 0; i < irep->objc; ++i) {
      gc_mark(pic, irep->obj[i]);
    }
    for (i = 0; i < irep->irepc; ++i) {
      gc_mark_object(pic, (struct object *) irep->irep[i]);
    }
    break;
  }
  case PIC_TYPE_VECTOR: {
    struct vector *vec = (struct vector *) obj;
    int i;
    for (i = 0; i < vec->len; ++i) {
      gc_mark(pic, vec->data[i]);
    }
    break;
  }
  case PIC_TYPE_DICT: {
    struct dict *dict = (struct dict *) obj;
    khash_t(dict) *h = &dict->hash;
    int it;
    for (it = 0; it != kh_end(h); ++it) {
      if (kh_exist(h, it)) {
        gc_mark_object(pic, (struct object *) kh_key(h, it));
        gc_mark(pic, kh_val(h, it));
      }
    }
    break;
  }
  case PIC_TYPE_RECORD: {
    struct record *rec = (struct record *) obj;
    gc_mark(pic, rec->datum);
    LOOP(rec->type);
    break;
  }
  case PIC_TYPE_SYMBOL: {
    struct symbol *sym = (struct symbol *) obj;
    LOOP(sym->str);
    break;
  }
  case PIC_TYPE_ATTR: {
    struct attr *attr = (struct attr *) obj;
    attr->prev = pic->gc_attrs;
    pic->gc_attrs = attr;
    break;
  }
  case PIC_TYPE_STRING: {
    struct string *str = (struct string *) obj;
    LOOP(str->rope);
    break;
  }
  case PIC_TYPE_ROPE_NODE: {
    struct rope_node *node = (struct rope_node *) obj;
    gc_mark_object(pic, (struct object *) node->s1);
    LOOP(node->s2);
    break;
  }

  case PIC_TYPE_ROPE_LEAF:
  case PIC_TYPE_BLOB:
  case PIC_TYPE_DATA:
    break;

  default:
    PIC_UNREACHABLE();
  }
}