@@ -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);
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) {
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;
56− cl -> info.c.args = allocate(vm, sizeof(VAL)*arity);
59+ cl -> info.c.args = (void*)((char*)cl + sizeof(ClosureType)
58 return (void*)cl;
62 return (void*)cl;
@@ -66,9 +70,10 @@ VAL MKFLOAT(VM* vm, double val) {
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;
@@ -133,9 +138,9 @@ void dumpVal(VAL v) {
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;
@@ -147,9 +152,9 @@ VAL idris_castStrInt(VM* vm, VAL i) {
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;
@@ -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.
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;