forked from nominolo/lambdachine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mm.c
110 lines (90 loc) · 2.44 KB
/
mm.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <stdlib.h>
#include <assert.h>
#include "mm.h"
/**
* Initialise the memory manager state.
*
* Currently we use a very simple semi-space garbage collector. The
* heap is split into two equally sized regions and objects are
* bump-allocated into one region. If the region is full, garbage
* collection occurs by coping all live objects into the other region
* and (implicitly) throw away all the remaining objects. The two
* regions then switch roles.
*
* @param heap_size The heap size in bytes. This value be must at
* least 1024 machine words.
*
* @return 0 if no error occurred. #ENOMEM if allocation of the heap
* failed.
*/
int MMState_init(MMState* state, StgWord heap_size)
{
StgPtr heap;
StgWord space_size;
assert(heap_size >= 1024 * sizeof(StgWord));
// heap_size should be a multiple of sizeof(StgWord)
heap_size = heap_size & ~((1 << LC_ALIGN_LOG2) - 1);
heap = (StgPtr)malloc(heap_size);
if (!heap)
return ENOMEM;
space_size = heap_size >> 1;
state->heap_bottom = heap;
state->heap_size = heap_size;
state->Hp = heap;
state->HpLim = heap + space_size;
state->from_space = heap + space_size + sizeof(StgWord);
state->root = heap;
return 0;
}
// obj_size is in *machine words*!
StgPtr new(MMState* state, StgWord obj_size)
{
if (state->Hp + obj_size > state->HpLim) {
flip(state);
if (state->Hp + obj_size > state->HpLim) {
// out of memory
exit(1);
}
}
state->Hp += obj_size;
return state->Hp - obj_size;
}
int flip(MMState* state)
{
// Just die when out of memory (for now)
return 0;
/*
StgPtr old_Hp;
old_Hp = state->Hp;
state->Hp = state->from_space;
state->from_space = old_Hp;
evac(state, state->root);
return 0;
*/
}
#define CONSTR 1
#define CONSTR_1_0 2
#define CONSTR_0_1 3
#define CONSTR_2_0 4
#define CONSTR_1_1 5
#define CONSTR_0_2 6
#define CONSTR_STATIC 7
int evac(MMState* state, StgPtr object)
{
unsigned i;
unsigned size = 1; //OBJ_SIZE(object);
StgPtr new_object = state->Hp;
// allocate memory
state->Hp += 1 + size;
// copy info table pointer
new_object[0] = object[0];
// Overwrite the old info table with a forwarding pointer.
// This
object[0] = (StgPtr)((StgWord)new_object | 1);
// copy object
for (i = 1; i <= size; ++i) {
new_object[i] = object[i];
}
//
object[0] = (StgWord)new_object;
}