on master help sign in
Avoid indirection for strings and take advantage of the 8 bytes in the union to reduce allocation size
commit990438977d70e0122049331c6869984f35764a1a authorJorge Acereda <jacereda@gmail.com> dateMon 19 Mar 2018, 11:40 (9 years ago) parent300a686
3 files changed+36−32
rts/idris_gc.c+2−3 rts/idris_rts.c+21−21 rts/idris_rts.h+13−8
rts/idris_gc.c+2−3
@@ -41,7 +41,7 @@ VAL copy(VM* vm, VAL x) {
4141 cl = MKPTRc(vm, GETPTR(x));
4242 break;
4343 case CT_MANAGEDPTR:
44− cl = MKMPTRc(vm, x->info.managed_ptr, x->sz);
44+ cl = MKMPTRc(vm, x->info.mptr, x->sz);
4545 break;
4646 case CT_BITS8:
4747 cl = idris_b8CopyForGC(vm, x);
@@ -107,8 +107,7 @@ void cheney(VM *vm) {
107107 heap_item->info.ptr = copy(vm, (VAL)(GETPTR(heap_item)));
108108 break;
109109 case CT_STROFFSET:
110− heap_item->info.str_offset
111− = copy(vm, heap_item->info.str_offset);
110+ heap_item->info.str_offset = copy(vm, heap_item->info.str_offset);
112111 break;
113112 default: // Nothing to copy
114113 break;
rts/idris_rts.c+21−21
@@ -222,9 +222,8 @@ void* allocate(size_t size, int outerlock) {
222222 VM* vm = global_vm;
223223#endif
224224
225− if ((size & 7)!=0) {
226− size = 8 + ((size >> 3) << 3);
227− }
225+ size += 7;
226+ size &= ~7;
228227
229228 size_t chunk_size = size + sizeof(size_t);
230229
@@ -260,10 +259,14 @@ void* allocate(size_t size, int outerlock) {
260259
261260}
262261
262+static size_t szMax(ssize_t a, ssize_t b) {
263+ return a > b? a : b;
264+}
265+
263266static Closure * allocStr(size_t len, int outer) {
264− Closure * cl = allocate(sizeof(*cl) + len + 1, outer);
267+ size_t sz = szMax(len + 1 - 8, 0);
268+ Closure * cl = allocate(sizeof(*cl) + sz, outer);
265269 SETTY(cl, CT_STRING);
266− cl->info.str = cl->data;
267270 cl->sz = len;
268271 return cl;
269272}
@@ -290,16 +293,13 @@ VAL MKFLOAT(VM* vm, double val) {
290293
291294VAL MKSTRlen(VM* vm, const char * str, size_t len) {
292295 Closure* cl = allocStr(len, 0);
293− if (str) {
294− memcpy(cl->info.str, str, len);
295− } else {
296− cl->info.str = NULL;
297− }
296+ memcpy(cl->info.str, str, len);
297+ cl->flag = str == NULL;
298298 return cl;
299299}
300300
301301VAL MKSTR(VM* vm, const char* str) {
302− return MKSTRlen(vm, str, str? strlen(str) : ~0);
302+ return MKSTRlen(vm, str, str? strlen(str) : 0);
303303}
304304
305305char* GETSTROFF(VAL stroff) {
@@ -339,7 +339,7 @@ VAL MKPTR(VM* vm, void* ptr) {
339339VAL MKMPTR(VM* vm, void* ptr, size_t size) {
340340 Closure* cl = allocate(sizeof(Closure) + size, 0);
341341 SETTY(cl, CT_MANAGEDPTR);
342− memcpy(cl->info.managed_ptr, ptr, size);
342+ memcpy(cl->info.mptr, ptr, size);
343343 cl->sz = size;
344344 return cl;
345345}
@@ -351,7 +351,7 @@ VAL MKFLOATc(VM* vm, double val) {
351351 return cl;
352352}
353353
354−VAL MKSTRclen(VM* vm, char* str, int len) {
354+VAL MKSTRclen(VM* vm, char* str, size_t len) {
355355 Closure* cl = allocStr(len, 1);
356356 memcpy(cl->info.str, str, len);
357357 return cl;
@@ -371,7 +371,7 @@ VAL MKPTRc(VM* vm, void* ptr) {
371371VAL MKMPTRc(VM* vm, void* ptr, size_t size) {
372372 Closure* cl = allocate(sizeof(Closure) + size, 1);
373373 SETTY(cl, CT_MANAGEDPTR);
374− memcpy(cl->info.managed_ptr, ptr, size);
374+ memcpy(cl->info.mptr, ptr, size);
375375 cl->sz = size;
376376 return cl;
377377}
@@ -567,8 +567,8 @@ VAL idris_castStrFloat(VM* vm, VAL i) {
567567VAL idris_concat(VM* vm, VAL l, VAL r) {
568568 char *rs = GETSTR(r);
569569 char *ls = GETSTR(l);
570− int llen = GETSTRLEN(l);
571− int rlen = GETSTRLEN(r);
570+ size_t llen = GETSTRLEN(l);
571+ size_t rlen = GETSTRLEN(r);
572572
573573 Closure* cl = allocStr(llen + rlen, 0);
574574 memcpy(cl->info.str, ls, llen);
@@ -677,7 +677,7 @@ VAL idris_strTail(VM* vm, VAL str) {
677677VAL idris_strCons(VM* vm, VAL x, VAL xs) {
678678 char *xstr = GETSTR(xs);
679679 int xval = GETINT(x);
680− int xlen = GETSTRLEN(xs);
680+ size_t xlen = GETSTRLEN(xs);
681681
682682 if (xval < 0x80) { // ASCII char
683683 Closure* cl = allocStr(xlen + 1, 0);
@@ -702,8 +702,8 @@ VAL idris_strIndex(VM* vm, VAL str, VAL i) {
702702}
703703
704704VAL idris_substr(VM* vm, VAL offset, VAL length, VAL str) {
705− int offset_val = GETINT(offset);
706− int length_val = GETINT(length);
705+ size_t offset_val = GETINT(offset);
706+ size_t length_val = GETINT(length);
707707 char* str_val = GETSTR(str);
708708
709709 // If the substring is a suffix, use idris_strShift to avoid reallocating
@@ -723,7 +723,7 @@ VAL idris_substr(VM* vm, VAL offset, VAL length, VAL str) {
723723
724724VAL idris_strRev(VM* vm, VAL str) {
725725 char *xstr = GETSTR(str);
726− int xlen = GETSTRLEN(str);
726+ size_t xlen = GETSTRLEN(str);
727727
728728 Closure* cl = allocStr(xlen, 0);
729729 idris_utf8_rev(xstr, cl->info.str);
@@ -893,7 +893,7 @@ VAL doCopyTo(VM* vm, VAL x) {
893893 cl = MKPTRc(vm, x->info.ptr);
894894 break;
895895 case CT_MANAGEDPTR:
896− cl = MKMPTRc(vm, x->info.managed_ptr, x->sz);
896+ cl = MKMPTRc(vm, x->info.mptr, x->sz);
897897 break;
898898 case CT_CDATA:
899899 cl = MKCDATAc(vm, x->info.c_heap_item);
rts/idris_rts.h+13−8
@@ -34,7 +34,9 @@ typedef struct Closure *VAL;
3434
3535typedef struct Closure {
3636 uint64_t ty:8;
37− uint64_t sz:56;
37+// True for null strings. Might be useful at some point for other types.
38+ uint64_t flag:1;
39+ uint64_t sz:55;
3840 union {
3941// A constructor, consisting of a tag (encoded in the sz field),
4042// an arity (encoded in 8 bits in the sz field), and arguments
@@ -47,15 +49,14 @@ typedef struct Closure {
4749 double f;
4850 VAL str_offset;
4951 void * ptr;
50− char * str;
52+ char str[0];
5153 uint8_t bits8;
5254 uint16_t bits16;
5355 uint32_t bits32;
5456 uint64_t bits64;
55− char managed_ptr[0]; // A foreign pointer, managed by the idris GC
57+ char mptr[0]; // A foreign pointer, managed by the idris GC
5658 CHeapItem* c_heap_item;
5759 } info;
58− char data[0];
5960} Closure;
6061
6162struct VM;
@@ -165,10 +166,14 @@ typedef void(*func)(VM*, VAL*);
165166#define REG1 (vm->reg1)
166167
167168// Retrieving values
168−#define GETSTR(x) (ISSTR(x) ? (((VAL)(x))->info.str) : GETSTROFF(x))
169−#define GETSTRLEN(x) (ISSTR(x) ? (((VAL)(x))->sz) : GETSTROFFLEN(x))
169+static inline char * getstr(VAL x) {
170+ return x->flag? NULL : x->info.str;
171+}
172+
173+#define GETSTR(x) (ISSTR(x) ? getstr((VAL)(x)) : GETSTROFF(x))
174+#define GETSTRLEN(x) (ISSTR(x) ? ((VAL)(x))->sz : GETSTROFFLEN(x))
170175#define GETPTR(x) (((VAL)(x))->info.ptr)
171−#define GETMPTR(x) (((VAL)(x))->info.managed_ptr)
176+#define GETMPTR(x) (((VAL)(x))->info.mptr)
172177#define GETFLOAT(x) (((VAL)(x))->info.f)
173178#define GETCDATA(x) (((VAL)(x))->info.c_heap_item)
174179
@@ -245,7 +250,7 @@ VAL MKCDATA(VM* vm, CHeapItem * item);
245250VAL MKFLOATc(VM* vm, double val);
246251VAL MKSTROFFc(VM* vm, VAL off);
247252VAL MKSTRc(VM* vm, char* str);
248−VAL MKSTRclen(VM* vm, char* str, int len);
253+VAL MKSTRclen(VM* vm, char* str, size_t len);
249254VAL MKPTRc(VM* vm, void* ptr);
250255VAL MKMPTRc(VM* vm, void* ptr, size_t size);
251256VAL MKCDATAc(VM* vm, CHeapItem * item);