-
Notifications
You must be signed in to change notification settings - Fork 0
/
gc.c
92 lines (73 loc) · 1.78 KB
/
gc.c
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
#include <stdlib.h>
#include <stdio.h>
#include "gc.h"
int *getBlock(int *p);
void mark(int *p);
void sweep();
// given function that returns bottom memory address of stack
void *stackBottom() {
unsigned long bottom;
FILE *statfp = fopen("/proc/self/stat", "r");
fscanf(statfp,
"%*d %*s %*c %*d %*d %*d %*d %*d %*u "
"%*u %*u %*u %*u %*u %*u %*d %*d "
"%*d %*d %*d %*d %*u %*u %*d "
"%*u %*u %*u %lu", &bottom);
fclose(statfp);
return (void *) bottom;
}
void gc() {
int ** max = (int**) stackBottom();
int *dummy;
int **p = &dummy;
while (p < max) {
mark(*p);
p++;
}
sweep();
coalesce();
}
// mark non-garbage blocks
void mark(int *p) {
// find block
// see if p points into the heap
// if it does, find the block it is in and mark it
int *firstblock = (int*)firstBlock();
int *lastblock = (int*)lastBlock();
int *ptr = (int*) p;
if (ptr < firstblock || ptr > lastblock) {
return;
}
int *b = getBlock(ptr);
if (isAllocated(b)) {
*b = *b + 2;
int bsize = *b/4;
int **p2 = (int**)b+1;
while (p2 <= (int**)(b + bsize)) {
mark(*p2);
p2 = p2 + 1;
}
}
}
// free non-marked blocks
void sweep() {
int *p = (int*)firstBlock();
int *end = (int*)lastBlock();
while (p != end) {
if (*p%4 != 3) {
myfree(p+1);
} else {
*p = *p-2;
}
p = (int*) nextBlock(p);
}
coalesce();
}
// return the header of input block
int *getBlock(int *p) {
int *block = (int*)firstBlock();
while ((int*)nextBlock(block) < p) {
block = (int*)nextBlock(block);
}
return block;
}