@@ -10,14 +10,19 @@
1010#include "idris_gc.h"
1111#include "idris_bitstring.h"
1212
13+
1314VM* init_vm(int stack_size, size_t heap_size,
1415 int max_threads, // not implemented yet
1516 int argc, char* argv[]) {
16− VAL* valstack = malloc(stack_size*sizeof(VAL));
17− int* intstack = malloc(stack_size*sizeof(int));
18− double* floatstack = malloc(stack_size*sizeof(double));
1917
2018 VM* vm = malloc(sizeof(VM));
19+ STATS_INIT_STATS(vm->stats)
20+ STATS_ENTER_INIT(vm->stats)
21+
22+ VAL* valstack = malloc(stack_size * sizeof(VAL));
23+ int* intstack = malloc(stack_size * sizeof(int));
24+ double* floatstack = malloc(stack_size*sizeof(double));
25+
2126 vm->valstack = valstack;
2227 vm->valstack_top = valstack;
2328 vm->valstack_base = valstack;
@@ -26,14 +31,9 @@ VM* init_vm(int stack_size, size_t heap_size,
2631 vm->floatstack = floatstack;
2732 vm->floatstack_ptr = floatstack;
2833 vm->stack_max = valstack + stack_size;
29− vm->heap = malloc(heap_size);
30− vm->oldheap = NULL;
31− vm->heap_next = vm->heap;
32− vm->heap_end = vm->heap + heap_size;
33− vm->heap_size = heap_size;
34− vm->collections = 0;
35− vm->allocations = 0;
36− vm->heap_growth = heap_size;
34+
35+ alloc_heap(&(vm->heap), heap_size);
36+
3737 vm->ret = NULL;
3838 vm->reg1 = NULL;
3939
@@ -60,25 +60,32 @@ VM* init_vm(int stack_size, size_t heap_size,
6060 vm->argv[i] = MKSTR(vm, argv[i]);
6161 }
6262
63+ STATS_LEAVE_INIT(vm->stats)
6364 return vm;
6465}
6566
66−void terminate(VM* vm) {
67+Stats terminate(VM* vm) {
68+ Stats stats = vm->stats;
69+ STATS_ENTER_EXIT(stats)
70+
6771 free(vm->inbox);
6872 free(vm->valstack);
6973 free(vm->intstack);
7074 free(vm->floatstack);
71− free(vm->heap);
75+ free_heap(&(vm->heap));
7276 free(vm->argv);
73− if (vm->oldheap != NULL) { free(vm->oldheap); }
77+
7478 pthread_mutex_destroy(&(vm -> inbox_lock));
7579 pthread_mutex_destroy(&(vm -> inbox_block));
7680 pthread_cond_destroy(&(vm -> inbox_waiting));
7781 free(vm);
82+
83+ STATS_LEAVE_EXIT(stats)
84+ return stats;
7885}
7986
8087void idris_requireAlloc(VM* vm, size_t size) {
81− if (!(vm -> heap_next + size < vm -> heap_end)) {
88+ if (!(vm->heap.next + size < vm->heap.end)) {
8289 idris_gc(vm);
8390 }
8491
@@ -109,13 +116,13 @@ void* allocate(VM* vm, size_t size, int outerlock) {
109116
110117 size_t chunk_size = size + sizeof(size_t);
111118
112− if (vm -> heap_next + chunk_size < vm -> heap_end) {
113− vm->allocations += chunk_size;
114− void* ptr = (void*)(vm->heap_next + sizeof(size_t));
115− *((size_t*)(vm->heap_next)) = chunk_size;
116− vm -> heap_next += chunk_size;
119+ if (vm->heap.next + chunk_size < vm->heap.end) {
120+ STATS_ALLOC(vm->stats, chunk_size)
121+ void* ptr = (void*)(vm->heap.next + sizeof(size_t));
122+ *((size_t*)(vm->heap.next)) = chunk_size;
123+ vm->heap.next += chunk_size;
117124
118− assert(vm->heap_next <= vm->heap_end);
125+ assert(vm->heap.next <= vm->heap.end);
119126
120127 memset(ptr, 0, size);
121128
@@ -215,7 +222,7 @@ void dumpStack(VM* vm) {
215222 for (root = vm->valstack; root < vm->valstack_top; ++root, ++i) {
216223 printf("%d: ", i);
217224 dumpVal(*root);
218− if (*root >= (VAL)(vm->heap) && *root < (VAL)(vm->heap_end)) { printf("OK"); }
225+ if (*root >= (VAL)(vm->heap.heap) && *root < (VAL)(vm->heap.end)) { printf("OK"); }
219226 printf("\n");
220227 }
221228 printf("RET: ");
@@ -408,12 +415,14 @@ void* runThread(void* arg) {
408415 callvm->processes--;
409416
410417 free(td);
411− terminate(vm);
418+
419+ Stats stats = terminate(vm);
420+ // aggregate_stats(&(td->vm->stats), &stats);
412421 return NULL;
413422}
414423
415424void* vmThread(VM* callvm, func f, VAL arg) {
416− VM* vm = init_vm(callvm->stack_max - callvm->valstack, callvm->heap_size,
425+ VM* vm = init_vm(callvm->stack_max - callvm->valstack, callvm->heap.size,
417426 callvm->max_threads,
418427 0, NULL);
419428 vm->processes=1; // since it can send and receive messages
@@ -500,12 +509,12 @@ void idris_sendMessage(VM* sender, VM* dest, VAL msg) {
500509 // So: we try to copy, if a collection happens, we do the copy again
501510 // under the assumption there's enough space this time.
502511
503− int gcs = dest->collections;
512+ int gcs = dest->stats.collections;
504513 pthread_mutex_lock(&dest->alloc_lock);
505514 VAL dmsg = copyTo(dest, msg);
506515 pthread_mutex_unlock(&dest->alloc_lock);
507516
508− if (dest->collections>gcs) {
517+ if (dest->stats.collections > gcs) {
509518 // a collection will have invalidated the copy
510519 pthread_mutex_lock(&dest->alloc_lock);
511520 dmsg = copyTo(dest, msg); // try again now there's room...