my first GC-just 4 fun (c)

/* 文件object.h */

#ifndef OBJECT_H
#define OBJECT_H
typedef enum {
    OBJ_INT,
    OBJ_PAIR
} ObjectType;

typedef struct sObject {
    ObjectType type; //type字段表示对象的类型要么int要么pair
    union {
        /* OBJ_INT */
        int value;

        /* OBJ_PAIR */
        struct {
                struct sObject* head;
                struct sObject* tail;
        };
    };
    unsigned char marked;

    /* the next object in the list of all object. */
    struct sObect* next;
} Object;
#define STACK_MAX 256
/* 基于栈的虚拟机 */
typedef struct {
    Object* stack[STACK_MAX];
    int stackSize;

    /* the first object in the list of all objects */
    Object* firstObject;

    int numObjects;//total num of currently allocated objects
    int maxObjects;//num of objects required to trigger a GC
} VM;
#endif

/* 文件object.c */

#include "object.h"
#include <memory.h>
#include <stdio.h>
#include <assert.h>
#define INI_GC_THRESHOLD 8
VM* newVM() {
    VM* vm=(VM*)malloc(sizeof(VM));
    vm->stackSize = 0;
    vm->firstObject = NULL;
    vm->numObjects = 0;
    vm->maxObjects = INI_GC_THRESHOLD;
    return vm;
}

void push(VM* vm,Object* value){
    assert(vm->stackSize < STACK_MAX);//, "Stack overflow!");
    vm->stack[vm->stackSize++]=value;
}

Object* pop(VM* vm) {
    assert(vm->stackSize > 0);//, "Stack underflow!");
    return vm->stack[--vm->stackSize];
}

Object* newObject(VM* vm, ObjectType type) {
    if (vm->numObjects == vm->maxObjects) gc(vm);
    Object* object=malloc(sizeof(Object));
    object->type = type;
    object->marked = 0;

    /* Insert it into the list of allocated objects. */
    object->next = vm->firstObject;
    vm->firstObject = object;
    vm->numObjects++;
    return object;
}

void pushInt(VM* vm,int intValue) {
    Object* object = newObject(vm,OBJ_INT);
    object->value = intValue;
    push(vm,object);
}

Object* pushPair(VM* vm) {
    Object* object = newObject(vm,OBJ_PAIR);
    object->tail = pop(vm);
    object->head = pop(vm);
    push(vm,object);
    return object;
}

void mark(Object* object) {
    /* If already marked, it's done. Check this first
     * to avoid recursing on cycles in the object graph.
     */
    if(object->marked) return;

    object->marked = 1;

    if(object->type == OBJ_PAIR){
        mark(object->head);
        mark(object->tail);
    }
}

void markAll(VM* vm) {
    int i=0;
    for(;i < vm->stackSize; i++){
        mark(vm->stack[i]);
    }
}

void sweep(VM* vm) {
    Object** object = &vm->firstObject;
    while(*object) {
        if(!(*object)->marked) {
            /* This object wasn't reached,
             * so remove it from the list and free it.
             */
            Object* unreached = *object;

            /* It was pointint to an unreached object,
             * but now it's been changed to pointing to the next.
             * Comparing to those who using 'p','q','temp' to remove
             * a object, this method is better.
             */
            *object = unreached->next;
            printf("free an object!\n");
            free(unreached);
            vm->numObjects--;
        } else {
            /* This object was reached, so unmark it(for the next GC) */
            (*object)->marked = 0;
            object = &(*object)->next;
        }
    }
}

void gc(VM* vm) {
    markAll(vm);
    sweep(vm);
    vm->maxObjects = vm->numObjects * 2;
}


/* 文件main.c */

#include <stdio.h>
#include <stdlib.h>
#include "object.h"

int main()
{
    VM* vm=newVM();
    int x;
    int order;
    unsigned char isExit=0;
    while(!isExit){
        printf("input order, 1.pushInt 2.pushPair 3.pop 0.exit (0/1/2/3):");
        scanf("%d",&order);
        switch(order){
            case 1:
                printf("input the value of integer:\n");
                scanf("%d",&x);
                pushInt(vm,x);
                break;
            case 2:
                pushPair(vm);
                break;
            case 3:
                pop(vm);
                break;
            case 0:
                isExit=1;
                break;
        }
        printf("\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值