@@ -189,13 +189,13 @@ void idris_doneAlloc(void) {
189189}
190190
191191int space(VM* vm, size_t size) {
192− return (vm->heap.next + size + sizeof(size_t) < vm->heap.end);
192+ return (vm->heap.next + size) < vm->heap.end;
193193}
194194
195195void* idris_alloc(size_t size) {
196196 Closure* cl = (Closure*) allocate(sizeof(Closure)+size, 0);
197197 SETTY(cl, CT_RAWDATA);
198− cl->sz = size;
198+ cl->extrasz = size;
199199 return (void*)(cl+1);
200200}
201201
@@ -208,8 +208,9 @@ void* idris_realloc(void* old, size_t old_size, size_t size) {
208208void idris_free(void* ptr, size_t size) {
209209}
210210
211−void* allocate(size_t size, int outerlock) {
211+void* allocate(size_t isize, int outerlock) {
212212// return malloc(size);
213+ size_t size = aligned(isize);
213214
214215#ifdef HAS_PTHREAD
215216 VM* vm = pthread_getspecific(vm_key);
@@ -222,16 +223,10 @@ void* allocate(size_t size, int outerlock) {
222223 VM* vm = global_vm;
223224#endif
224225
225− size += 7;
226− size &= ~7;
227−
228− size_t chunk_size = size + sizeof(size_t);
229−
230− if (vm->heap.next + chunk_size < vm->heap.end) {
231− STATS_ALLOC(vm->stats, chunk_size)
232− void* ptr = (void*)(vm->heap.next + sizeof(size_t));
233− *((size_t*)(vm->heap.next)) = chunk_size;
234− vm->heap.next += chunk_size;
226+ if (vm->heap.next + size < vm->heap.end) {
227+ STATS_ALLOC(vm->stats, size)
228+ char* ptr = vm->heap.next;
229+ vm->heap.next += size;
235230
236231 assert(vm->heap.next <= vm->heap.end);
237232
@@ -241,7 +236,7 @@ void* allocate(size_t size, int outerlock) {
241236 pthread_mutex_unlock(&vm->alloc_lock);
242237 }
243238#endif
244− return ptr;
239+ return (void*)ptr;
245240 } else {
246241 // If we're trying to allocate something bigger than the heap,
247242 // grow the heap here so that the new heap is big enough.
@@ -259,16 +254,12 @@ void* allocate(size_t size, int outerlock) {
259254
260255}
261256
262−static size_t szMax(ssize_t a, ssize_t b) {
263− return a > b? a : b;
264−}
265−
266257static Closure * allocStr(size_t len, int outer) {
267− size_t sz = szMax(len + 1 - 8, 0);
268− Closure * cl = allocate(sizeof(*cl) + sz, outer);
269− SETTY(cl, CT_STRING);
270− cl->sz = len;
271− return cl;
258+ Closure * cl = allocate(sizeof(Closure) + len + 1, outer);
259+ SETTY(cl, CT_STRING);
260+ cl->extrasz = len + 1;
261+ cl->info.slen = len;
262+ return cl;
272263}
273264
274265/* Now a macro
@@ -293,8 +284,9 @@ VAL MKFLOAT(VM* vm, double val) {
293284
294285VAL MKSTRlen(VM* vm, const char * str, size_t len) {
295286 Closure* cl = allocStr(len, 0);
296− memcpy(cl->info.str, str, len);
297− cl->flag = str == NULL;
287+ memcpy(cl->extra.str, str, len);
288+ if (str == NULL)
289+ cl->info.slen = ~0;
298290 return cl;
299291}
300292
@@ -304,13 +296,13 @@ VAL MKSTR(VM* vm, const char* str) {
304296
305297char* GETSTROFF(VAL stroff) {
306298 // Assume STROFF
307− return stroff->info.str_offset->info.str + stroff->sz;
299+ return stroff->extra.basestr[0]->extra.str + stroff->info.soffset;
308300}
309301
310302size_t GETSTROFFLEN(VAL stroff) {
311303 // Assume STROFF
312304 // we're working in char* here so no worries about utf8 char length
313− return stroff->info.str_offset->sz - stroff->sz;
305+ return stroff->extra.basestr[0]->info.slen - stroff->info.soffset;
314306}
315307
316308VAL MKCDATA(VM* vm, CHeapItem * item) {
@@ -339,8 +331,8 @@ VAL MKPTR(VM* vm, void* ptr) {
339331VAL MKMPTR(VM* vm, void* ptr, size_t size) {
340332 Closure* cl = allocate(sizeof(Closure) + size, 0);
341333 SETTY(cl, CT_MANAGEDPTR);
342− memcpy(cl->info.mptr, ptr, size);
343− cl->sz = size;
334+ memcpy(cl->extra.mptr, ptr, size);
335+ cl->extrasz = size;
344336 return cl;
345337}
346338
@@ -353,7 +345,7 @@ VAL MKFLOATc(VM* vm, double val) {
353345
354346VAL MKSTRclen(VM* vm, char* str, size_t len) {
355347 Closure* cl = allocStr(len, 1);
356− memcpy(cl->info.str, str, len);
348+ memcpy(cl->extra.str, str, len);
357349 return cl;
358350}
359351
@@ -371,8 +363,8 @@ VAL MKPTRc(VM* vm, void* ptr) {
371363VAL MKMPTRc(VM* vm, void* ptr, size_t size) {
372364 Closure* cl = allocate(sizeof(Closure) + size, 1);
373365 SETTY(cl, CT_MANAGEDPTR);
374− memcpy(cl->info.mptr, ptr, size);
375− cl->sz = size;
366+ memcpy(cl->extra.mptr, ptr, size);
367+ cl->extrasz = size;
376368 return cl;
377369}
378370
@@ -437,17 +429,17 @@ void dumpVal(VAL v) {
437429 switch(GETTY(v)) {
438430 case CT_CON:
439431 printf("%d[", (int)TAG(v));
440− for(i = 0; i < ARITY(v); ++i) {
441− dumpVal(v->info.cargs[i]);
432+ for(i = 0; i < CARITY(v); ++i) {
433+ dumpVal(v->extra.cargs[i]);
442434 }
443435 printf("] ");
444436 break;
445437 case CT_STRING:
446− printf("STR[%s]", v->info.str);
438+ printf("STR[%s]", v->extra.str);
447439 break;
448440 case CT_STROFFSET:
449441 printf("OFFSET[");
450− dumpVal((VAL)(v->info.str_offset));
442+ dumpVal((VAL)(v->extra.basestr[0]));
451443 printf("]");
452444 break;
453445 case CT_FWD:
@@ -509,7 +501,7 @@ void idris_memmove(void* dest, void* src, i_int dest_offset, i_int src_offset, i
509501VAL idris_castIntStr(VM* vm, VAL i) {
510502 int x = (int) GETINT(i);
511503 Closure* cl = allocStr(16, 0);
512− cl->sz = sprintf(cl->info.str, "%d", x);
504+ cl->info.slen = sprintf(cl->extra.str, "%d", x);
513505 return cl;
514506}
515507
@@ -521,22 +513,22 @@ VAL idris_castBitsStr(VM* vm, VAL i) {
521513 case CT_BITS8:
522514 // max length 8 bit unsigned int str 3 chars (256)
523515 cl = allocStr(4, 0);
524− cl->sz = sprintf(cl->info.str, "%" PRIu8, GETBITS8(i));
516+ cl->info.slen = sprintf(cl->extra.str, "%" PRIu8, GETBITS8(i));
525517 break;
526518 case CT_BITS16:
527519 // max length 16 bit unsigned int str 5 chars (65,535)
528520 cl = allocStr(6, 0);
529− cl->sz = sprintf(cl->info.str, "%" PRIu16, GETBITS16(i));
521+ cl->info.slen = sprintf(cl->extra.str, "%" PRIu16, GETBITS16(i));
530522 break;
531523 case CT_BITS32:
532524 // max length 32 bit unsigned int str 10 chars (4,294,967,295)
533525 cl = allocStr(11, 0);
534− cl->sz = sprintf(cl->info.str, "%" PRIu32, GETBITS32(i));
526+ cl->info.slen = sprintf(cl->extra.str, "%" PRIu32, GETBITS32(i));
535527 break;
536528 case CT_BITS64:
537529 // max length 64 bit unsigned int str 20 chars (18,446,744,073,709,551,615)
538530 cl = allocStr(21, 0);
539− cl->sz = sprintf(cl->info.str, "%" PRIu64, GETBITS64(i));
531+ cl->info.slen = sprintf(cl->extra.str, "%" PRIu64, GETBITS64(i));
540532 break;
541533 default:
542534 fprintf(stderr, "Fatal Error: ClosureType %d, not an integer type", ty);
@@ -556,7 +548,7 @@ VAL idris_castStrInt(VM* vm, VAL i) {
556548
557549VAL idris_castFloatStr(VM* vm, VAL i) {
558550 Closure* cl = allocStr(32, 0);
559− cl->sz = snprintf(cl->info.str, 32, "%.16g", GETFLOAT(i));
551+ cl->info.slen = snprintf(cl->extra.str, 32, "%.16g", GETFLOAT(i));
560552 return cl;
561553}
562554
@@ -571,8 +563,8 @@ VAL idris_concat(VM* vm, VAL l, VAL r) {
571563 size_t rlen = GETSTRLEN(r);
572564
573565 Closure* cl = allocStr(llen + rlen, 0);
574− memcpy(cl->info.str, ls, llen);
575− memcpy(cl->info.str + llen, rs, rlen);
566+ memcpy(cl->extra.str, ls, llen);
567+ memcpy(cl->extra.str + llen, rs, rlen);
576568 return cl;
577569}
578570
@@ -634,12 +626,11 @@ VAL idris_strHead(VM* vm, VAL str) {
634626 return idris_strIndex(vm, str, 0);
635627}
636628
637−VAL MKSTROFFc(VM* vm, VAL off) {
638− Closure* cl = allocate(sizeof(Closure), 1);
629+VAL MKSTROFFc(VM* vm, VAL basestr) {
630+ Closure* cl = allocate(sizeof(Closure) + sizeof(VAL), 1);
639631 SETTY(cl, CT_STROFFSET);
640− cl->info.str_offset = off->info.str_offset;
641− cl->sz = off->sz;
642−
632+ cl->extrasz = sizeof(VAL);
633+ cl->extra.basestr[0] = basestr;
643634 return cl;
644635}
645636
@@ -647,22 +638,20 @@ VAL idris_strShift(VM* vm, VAL str, int num) {
647638 // If there's no room, just copy the string, or we'll have a problem after
648639 // gc moves str
649640 if (space(vm, sizeof(Closure))) {
650− Closure* cl = allocate(sizeof(Closure), 0);
651− SETTY(cl, CT_STROFFSET);
652− cl->info.str_offset = cl->info.str_offset;
653−
654641 int offset = 0;
655642 VAL root = str;
643+ Closure* cl = allocate(sizeof(Closure) + sizeof(VAL), 0);
644+ SETTY(cl, CT_STROFFSET);
645+ cl->extrasz = sizeof(VAL);
656646
657647 while(root!=NULL && !ISSTR(root)) { // find the root, carry on.
658648 // In theory, at most one step here!
659− offset += root->sz;
660− root = root->info.str_offset;
649+ offset += root->info.soffset;
650+ root = root->extra.basestr[0];
661651 }
662652
663− cl->info.str_offset = root;
664− cl->sz = offset+idris_utf8_findOffset(GETSTR(str), num);
665−
653+ cl->extra.basestr[0] = root;
654+ cl->info.soffset = offset+idris_utf8_findOffset(GETSTR(str), num);
666655 return cl;
667656 } else {
668657 char* nstr = GETSTR(str);
@@ -681,16 +670,16 @@ VAL idris_strCons(VM* vm, VAL x, VAL xs) {
681670
682671 if (xval < 0x80) { // ASCII char
683672 Closure* cl = allocStr(xlen + 1, 0);
684− cl->info.str[0] = (char)(GETINT(x));
685− memcpy(cl->info.str+1, xstr, xlen);
673+ cl->extra.str[0] = (char)(GETINT(x));
674+ memcpy(cl->extra.str+1, xstr, xlen);
686675 return cl;
687676 } else {
688677 char *init = idris_utf8_fromChar(xval);
689678 size_t ilen = strlen(init);
690679 int newlen = ilen + xlen;
691680 Closure* cl = allocStr(newlen, 0);
692− memcpy(cl->info.str, init, ilen);
693− memcpy(cl->info.str + ilen, xstr, xlen);
681+ memcpy(cl->extra.str, init, ilen);
682+ memcpy(cl->extra.str + ilen, xstr, xlen);
694683 free(init);
695684 return cl;
696685 }
@@ -715,8 +704,8 @@ VAL idris_substr(VM* vm, VAL offset, VAL length, VAL str) {
715704 char *end = idris_utf8_advance(start, length_val);
716705 size_t sz = end - start;
717706 Closure* newstr = allocStr(sz, 0);
718− memcpy(newstr->info.str, start, sz);
719− newstr->info.str[sz] = '\0';
707+ memcpy(newstr->extra.str, start, sz);
708+ newstr->extra.str[sz] = '\0';
720709 return newstr;
721710 }
722711}
@@ -726,7 +715,7 @@ VAL idris_strRev(VM* vm, VAL str) {
726715 size_t xlen = GETSTRLEN(str);
727716
728717 Closure* cl = allocStr(xlen, 0);
729− idris_utf8_rev(xstr, cl->info.str);
718+ idris_utf8_rev(xstr, cl->extra.str);
730719 return cl;
731720}
732721
@@ -755,17 +744,17 @@ VAL idris_newArray(VM* vm, int size, VAL def) {
755744 int i;
756745 allocArray(cl, vm, size, 0);
757746 for(i=0; i<size; ++i) {
758− cl->info.array[i] = def;
747+ cl->extra.array[i] = def;
759748 }
760749 return cl;
761750}
762751
763752void idris_arraySet(VAL arr, int index, VAL newval) {
764− arr->info.array[index] = newval;
753+ arr->extra.array[index] = newval;
765754}
766755
767756VAL idris_arrayGet(VAL arr, int index) {
768− return arr->info.array[index];
757+ return arr->extra.array[index];
769758}
770759
771760VAL idris_systemInfo(VM* vm, VAL index) {
@@ -846,11 +835,19 @@ void* idris_stopThread(VM* vm) {
846835 return NULL;
847836}
848837
838+static VAL doCopyTo(VM* vm, VAL x);
839+
840+static void copyArray(VM* vm, VAL * dst, VAL * src, size_t len) {
841+ size_t i;
842+ for(i = 0; i < len; ++i)
843+ dst[i] = doCopyTo(vm, src[i]);
844+}
845+
846+
849847// VM is assumed to be a different vm from the one x lives on
850848
851−VAL doCopyTo(VM* vm, VAL x) {
852− int i, ar, len;
853− VAL* argptr;
849+static VAL doCopyTo(VM* vm, VAL x) {
850+ int ar, len;
854851 Closure* cl;
855852 if (x==NULL || ISINT(x)) {
856853 return x;
@@ -862,41 +859,31 @@ VAL doCopyTo(VM* vm, VAL x) {
862859 cl = x;
863860 } else {
864861 allocCon(cl, vm, CTAG(x), ar, 1);
865−
866− argptr = cl->info.cargs;
867− for(i = 0; i < ar; ++i) {
868− *argptr = doCopyTo(vm, x->info.cargs[i]); // recursive version
869− argptr++;
870− }
862+ copyArray(vm, cl->extra.cargs, x->extra.cargs, ar);
871863 }
872864 break;
873865 case CT_ARRAY:
874− len = x->sz;
866+ len = CELEM(x);
875867 allocArray(cl, vm, len, 1);
876−
877− argptr = cl->info.array;
878− for(i = 0; i < len; ++i) {
879− *argptr = doCopyTo(vm, x->info.array[i]); // recursive version
880− argptr++;
881− }
868+ copyArray(vm, cl->extra.array, x->extra.array, len);
882869 break;
883870 case CT_FLOAT:
884− cl = MKFLOATc(vm, x->info.f);
871+ cl = MKFLOATc(vm, GETFLOAT(x));
885872 break;
886873 case CT_STRING:
887− cl = MKSTRc(vm, x->info.str);
874+ cl = MKSTRclen(vm, x->extra.str, getstrlen(x));
888875 break;
889876 case CT_BIGINT:
890− cl = MKBIGMc(vm, x->info.ptr);
877+ cl = MKBIGMc(vm, GETPTR(x));
891878 break;
892879 case CT_PTR:
893− cl = MKPTRc(vm, x->info.ptr);
880+ cl = MKPTRc(vm, GETPTR(x));
894881 break;
895882 case CT_MANAGEDPTR:
896− cl = MKMPTRc(vm, x->info.mptr, x->sz);
883+ cl = MKMPTRc(vm, x->extra.mptr, x->extrasz);
897884 break;
898885 case CT_CDATA:
899− cl = MKCDATAc(vm, x->info.c_heap_item);
886+ cl = MKCDATAc(vm, GETCDATA(x));
900887 break;
901888 case CT_BITS8:
902889 cl = idris_b8CopyForGC(vm, x);
@@ -912,7 +899,7 @@ VAL doCopyTo(VM* vm, VAL x) {
912899 break;
913900 case CT_RAWDATA:
914901 {
915− size_t size = x->sz + sizeof(Closure);
902+ size_t size = sizeof(Closure) + x->extrasz;
916903 cl = allocate(size, 0);
917904 memcpy(cl, x, size);
918905 }
@@ -1148,9 +1135,9 @@ void init_nullaries(void) {
11481135 VAL cl;
11491136 nullary_cons = malloc(256 * sizeof(VAL));
11501137 for(i = 0; i < 256; ++i) {
1151− cl = malloc(sizeof(Closure));
1138+ cl = calloc(1, sizeof(Closure));
11521139 SETTY(cl, CT_CON);
1153− cl->sz = i << 8;
1140+ cl->info.tag = i;
11541141 nullary_cons[i] = cl;
11551142 }
11561143}