on master help sign in
Fix GC error
f2766a6Edwin Brady
rts/idris_gc.c+2−2
@@ -67,6 +67,7 @@ void cheney(VM *vm) {
67void gc(VM* vm) {
67void gc(VM* vm) {
68 char* newheap = malloc(vm -> heap_size);
68 char* newheap = malloc(vm -> heap_size);
69 char* oldheap = vm -> heap;
69 char* oldheap = vm -> heap;
70+ if (vm->oldheap != NULL) free(vm->oldheap);
70
71
71 vm->heap = newheap;
72 vm->heap = newheap;
72 vm->heap_next = newheap;
73 vm->heap_next = newheap;
@@ -88,6 +89,5 @@ void gc(VM* vm) {
88 if ((vm->heap_next - vm->heap) > vm->heap_size >> 1) {
89 if ((vm->heap_next - vm->heap) > vm->heap_size >> 1) {
89 vm->heap_size += vm->heap_growth;
90 vm->heap_size += vm->heap_growth;
90 }
91 }
91−
92− free(oldheap);
92+ vm->oldheap = oldheap;
93}
93}
rts/idris_main.c+1
@@ -4,6 +4,7 @@ int main(int argc, char* argv[]) {
4 _idris_main(vm, NULL);
4 _idris_main(vm, NULL);
5#ifdef IDRIS_TRACE
5#ifdef IDRIS_TRACE
6 printf("\nStack: %p %p\n", vm->valstack, vm->valstack_top);
6 printf("\nStack: %p %p\n", vm->valstack, vm->valstack_top);
7+ printf("Total allocations: %d\n", vm->allocations);
7 printf("GCs: %d\n", vm->collections);
8 printf("GCs: %d\n", vm->collections);
8 printf("Final heap size %d\n", (int)(vm->heap_size));
9 printf("Final heap size %d\n", (int)(vm->heap_size));
9 printf("Final heap use %d\n", (int)(vm->heap_next - vm->heap));
10 printf("Final heap use %d\n", (int)(vm->heap_next - vm->heap));
rts/idris_rts.c+20−10
@@ -22,10 +22,12 @@ VM* init_vm(int stack_size, size_t heap_size) {
22 vm -> floatstack_ptr = floatstack;
22 vm -> floatstack_ptr = floatstack;
23 vm -> stack_max = stack_size;
23 vm -> stack_max = stack_size;
24 vm -> heap = malloc(heap_size);
24 vm -> heap = malloc(heap_size);
25+ vm -> oldheap = NULL;
25 vm -> heap_next = vm -> heap;
26 vm -> heap_next = vm -> heap;
26 vm -> heap_end = vm -> heap + heap_size;
27 vm -> heap_end = vm -> heap + heap_size;
27 vm -> heap_size = heap_size;
28 vm -> heap_size = heap_size;
28 vm -> collections = 0;
29 vm -> collections = 0;
30+ vm -> allocations = 0;
29 vm -> heap_growth = heap_size;
31 vm -> heap_growth = heap_size;
30 vm -> ret = NULL;
32 vm -> ret = NULL;
31 return vm;
33 return vm;
@@ -35,6 +37,7 @@ void* allocate(VM* vm, size_t size) {
35 if ((size & 7)!=0) {
37 if ((size & 7)!=0) {
36 size = 8 + ((size >> 3) << 3);
38 size = 8 + ((size >> 3) << 3);
37 }
39 }
40+ vm->allocations += size+sizeof(size_t)*2;
38 if (vm -> heap_next + size < vm -> heap_end) {
41 if (vm -> heap_next + size < vm -> heap_end) {
39 void* ptr = (void*)(((size_t*)(vm->heap_next))+2);
42 void* ptr = (void*)(((size_t*)(vm->heap_next))+2);
40 *((size_t*)(vm->heap_next)) = size+sizeof(size_t)*2;
43 *((size_t*)(vm->heap_next)) = size+sizeof(size_t)*2;
@@ -48,12 +51,13 @@ void* allocate(VM* vm, size_t size) {
48
51
49void* allocCon(VM* vm, int arity) {
52void* allocCon(VM* vm, int arity) {
50 Closure* cl = allocate(vm, sizeof(ClosureType) +
53 Closure* cl = allocate(vm, sizeof(ClosureType) +
51− sizeof(con));
54+ sizeof(con) + sizeof(VAL)*arity);
52 cl -> ty = CON;
55 cl -> ty = CON;
53 if (arity == 0) {
56 if (arity == 0) {
54 cl -> info.c.args = NULL;
57 cl -> info.c.args = NULL;
55 } else {
58 } else {
56− cl -> info.c.args = allocate(vm, sizeof(VAL)*arity);
59+ cl -> info.c.args = (void*)((char*)cl + sizeof(ClosureType)
60+ + sizeof(con));
57 }
61 }
58 return (void*)cl;
62 return (void*)cl;
59}
63}
@@ -66,9 +70,10 @@ VAL MKFLOAT(VM* vm, double val) {
66}
70}
67
71
68VAL MKSTR(VM* vm, char* str) {
72VAL MKSTR(VM* vm, char* str) {
69− Closure* cl = allocate(vm, sizeof(ClosureType) + sizeof(char*));
73+ Closure* cl = allocate(vm, sizeof(ClosureType) + sizeof(char*) +
74+ sizeof(char)*strlen(str)+1);
70 cl -> ty = STRING;
75 cl -> ty = STRING;
71− cl -> info.str = allocate(vm, sizeof(char)*strlen(str)+1);
76+ cl -> info.str = (char*)cl + sizeof(ClosureType) + sizeof(char*);
72 strcpy(cl -> info.str, str);
77 strcpy(cl -> info.str, str);
73 return cl;
78 return cl;
74}
79}
@@ -133,9 +138,9 @@ void dumpVal(VAL v) {
133}
138}
134
139
135VAL idris_castIntStr(VM* vm, VAL i) {
140VAL idris_castIntStr(VM* vm, VAL i) {
136− Closure* cl = allocate(vm, sizeof(ClosureType) + sizeof(char*));
141+ Closure* cl = allocate(vm, sizeof(ClosureType) + sizeof(char*) + sizeof(char)*16);
137 cl -> ty = STRING;
142 cl -> ty = STRING;
138− cl -> info.str = allocate(vm, sizeof(char)*16);
143+ cl -> info.str = (char*)cl + sizeof(ClosureType) + sizeof(char*);
139 sprintf(cl -> info.str, "%ld", GETINT(i));
144 sprintf(cl -> info.str, "%ld", GETINT(i));
140 return cl;
145 return cl;
141}
146}
@@ -147,9 +152,9 @@ VAL idris_castStrInt(VM* vm, VAL i) {
147}
152}
148
153
149VAL idris_castFloatStr(VM* vm, VAL i) {
154VAL idris_castFloatStr(VM* vm, VAL i) {
150− Closure* cl = allocate(vm, sizeof(ClosureType) + sizeof(char*));
155+ Closure* cl = allocate(vm, sizeof(ClosureType) + sizeof(char*) + sizeof(char)*32);
151 cl -> ty = STRING;
156 cl -> ty = STRING;
152− cl -> info.str = allocate(vm, sizeof(char)*32);
157+ cl -> info.str = (char*)cl + sizeof(ClosureType) + sizeof(char*);
153 sprintf(cl -> info.str, "%g", GETFLOAT(i));
158 sprintf(cl -> info.str, "%g", GETFLOAT(i));
154 return cl;
159 return cl;
155}
160}
@@ -161,10 +166,15 @@ VAL idris_castStrFloat(VM* vm, VAL i) {
161VAL idris_concat(VM* vm, VAL l, VAL r) {
166VAL idris_concat(VM* vm, VAL l, VAL r) {
162 char *ls = GETSTR(l);
167 char *ls = GETSTR(l);
163 char *rs = GETSTR(r);
168 char *rs = GETSTR(r);
169+ Closure* cl = allocate(vm, sizeof(ClosureType) + sizeof(char*) +
170+ strlen(ls) + strlen(rs) + 1);
171+ // Oops! problem if the second allocate triggers a gc because cl has
172+ // to be a root. Fix by allocating all in one go.
164
173
165− Closure* cl = allocate(vm, sizeof(ClosureType) + sizeof(char*));
174+ // Also note that l/r may be in from space, so don't delete after collection,
175+ // rather, delete just before the next collection.
166 cl -> ty = STRING;
176 cl -> ty = STRING;
167− cl -> info.str = allocate(vm, sizeof(char)*(strlen(ls)+strlen(rs)+1));
177+ cl -> info.str = (char*)cl + sizeof(ClosureType) + sizeof(char*);
168 strcpy(cl -> info.str, ls);
178 strcpy(cl -> info.str, ls);
169 strcat(cl -> info.str, rs);
179 strcat(cl -> info.str, rs);
170 return cl;
180 return cl;
rts/idris_rts.h+2
@@ -41,11 +41,13 @@ typedef struct {
41 int* intstack_ptr;
41 int* intstack_ptr;
42 double* floatstack_ptr;
42 double* floatstack_ptr;
43 char* heap;
43 char* heap;
44+ char* oldheap;
44 char* heap_next;
45 char* heap_next;
45 char* heap_end;
46 char* heap_end;
46 int stack_max;
47 int stack_max;
47 size_t heap_size;
48 size_t heap_size;
48 size_t heap_growth;
49 size_t heap_growth;
50+ int allocations;
49 int collections;
51 int collections;
50 VAL ret;
52 VAL ret;
51} VM;
53} VM;