void gc_major() { #ifdef DEBUG_GC printf("gc: major collection initiated with end old region %zu\n", (uintptr_t)(heap->end_old)); #endif #ifdef DEBUG_HEAP printf("gc: before heap copy: stage 1 major collection\n"); print_heap(); #endif // collect from old to reserve gc_copy(old, reserve); // adjust heap pointers after collection heap->end_reserve = heap->reserve_avail; #ifdef VERIFY_HEAP verify_reserve_heap(); #endif #ifdef DEBUG_HEAP printf("gc: before heap copy: stage 2 major collection\n"); print_heap(); #endif // block move reserve region back to old heap heap->old_avail = heap->start; gc_copy(reserve, old); nuke_assigns(); // adjust heap pointers after collection heap->end_old = heap->old_avail; heap->reserve_avail = heap->end_old; // reset partition of the reserve and nursery to half of non-old region heap->end_reserve = heap->end_old + heap_reserve_nursery_midpoint(); heap->nursery_avail = heap->end_reserve; #ifdef DEBUG_HEAP printf("gc: after heap copy\n"); print_heap_region(); print_heap(); #endif }
Object* gc_copy(VM* vm, Object* object) { ObjectHeader* head = &((ObjectHeader*)object)[-1]; debug("gc copy %p\n",head); long size; if (!heap_find(vm, head)) return object; long* bitmap; Object* obj; switch(head->type) { case OBJ_BOXED_ARRAY: obj = gc_alloc((ObjectType)head->type, head->size); size = ((int)head->size) / sizeof(long); debug("size=%ld\n",size); for(int i = 0; i < size; i++) obj->field[i] = gc_copy(vm,object->field[i]); break; case OBJ_PAIR: obj = gc_alloc((ObjectType)head->type, head->size); obj->fst = gc_copy(vm,object->fst); obj->snd = gc_copy(vm,object->snd); break; case OBJ_UNBOXED_ARRAY: case OBJ_VM: obj = gc_alloc((ObjectType)head->type, head->size); memcpy(obj, object, head->size); break; case OBJ_RECORD: size = ((int)head->size) / sizeof(long); obj = gc_alloc((ObjectType)head->type, head->size); memcpy(obj, object, head->size); bitmap = &object->longs[size]; for(int i = 0; i < size; i++) { if(bitmap[i/sizeof(long)] & (1 << (i % sizeof(long)))) obj->field[i] = gc_copy(vm,object->field[i]); } break; } return obj; }
/****************************************************************** * * Simple generational collection (appel algorithm) * ******************************************************************/ void gc_minor() { #ifdef DEBUG_GC printf("gc: minor collection initiated with nursery start %zu\n", (uintptr_t)(heap->end_reserve)); #endif #ifdef DEBUG_HEAP printf("gc: before heap copy\n"); print_heap(); #endif // collect from nursery to reserve gc_copy(nursery, reserve); prune_assigns(reserve); #ifdef VERIFY_HEAP verify_reserve_heap(); #endif // adjust heap pointers after collection // the old region is now redefined to the extent of the used reserve heap->end_old = heap->reserve_avail; // reset partition of the reserve and nursery to half of non-old region heap->end_reserve = heap->end_old + heap_reserve_nursery_midpoint(); heap->nursery_avail = heap->end_reserve; #ifdef DEBUG_HEAP printf("gc: after heap copy\n"); print_heap_region(); print_heap(); #endif }
Object* vm_get_record(VM* _vm) { return gc_copy(_vm, _vm->record); }