-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlispyGarbageCollection.c
More file actions
124 lines (100 loc) · 2.33 KB
/
Copy pathlispyGarbageCollection.c
File metadata and controls
124 lines (100 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* This part is essentially building a simple garbage collector*/
typedef enum {
OBJ_INT,
OBJ_PAIR
} ObjectType;
typedef struct sObject {
unsigned char marked;
ObjectType type;
struct sObject* next;
union {
/* OBJ_INT */
int value;
/* OBJ_PAIR */
struct {
struct sObject* head;
struct sObject* tail;
};
};
} Object;
/*This part is for writing what I want the VM*/
#define STACK_MAX 256
typedef struct {
/*The total number of currently allocated objects*/
int numObjects;
/*The number of objects required to trigger a GC */
int maxObjects;
Object* stack[STACK_MAX];
int stackSize;
} VM;
VM* newVM() {
VM* vm = malloc(sizeof(VM));
vm->stackSize = 0;
vm->numObjects = 0;
vm->maxObjects = INITIAL_GC_THRESHOLD;
return vm;
}
void push(VM* vm, Object* value) {
assert(vm->stackSize < STACK_MAX, "Stack ovreflow!");
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;
}
/*Mark and Sweep implementation*/
void markAll(VM* vm){
for (int i = 0; i < vm->stackSize; i++) {
mark(vm->stack[i]);
}
}
void mark(Object* object) {
if (object->marked) return;
object->marked = 1;
if (object->type == OBJ_PAIR){
mark(object->head);
mark(object->tail);
}
}
void sweep(VM* vm){
Object** object = &vm->firstObject;
while (*object){
if(!(*object)->marked){
Object* unreached = *object;
*object = unreached->next;
free(unreached);
} else {
(*object)->marked = 0;
object = &(*object)->next;
}
}
}
void gc(VM* vm) {
int numObjects = vm->numObjects;
markAll(vm);
sweep(vm);
vm->maxObjects = vm->numObjects * 2;
}