diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-04-28 22:52:48 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-04-28 22:52:48 -0700 |
commit | c023a09e3faeef479ba866445a7a346b8e9c3f8a (patch) | |
tree | f819b764f7a41d92361fd3bec5ea843cd1164215 | |
parent | e5174a9dac601791af64903f44b8ab4a5e82621e (diff) | |
download | txr-c023a09e3faeef479ba866445a7a346b8e9c3f8a.tar.gz txr-c023a09e3faeef479ba866445a7a346b8e9c3f8a.tar.bz2 txr-c023a09e3faeef479ba866445a7a346b8e9c3f8a.zip |
ffi: sane calculation of rtsize.
We are wastefully giving structs and arrays a position in the
rtvec. They do not need one. Let's calculate like this. During
compilation, let's assign a rtsize value of 1 to types which
need to occupy a position. During the tree walk which assigns
the positions, let's use this as a Boolean value indicating
whether to assign and index or not. After the tree walk, the
final counter value indictates the rtsize for the whole
aggregate, and we store that in the rtsize of the root type
node.
* ffi.c (make_ffi_type_struct, make_ffi_type_array): Do not
add up the rtsizes of the elements/members and thus do not
install the total size as this type's rtsize. Leave the rtsize
zero. We revert to a variation of the previous method of
determining whether to install the in handler, but using a
slightly different criterion: if any child element has a
nonzero rtsize or if it has an in handler.
(assign_rtindices_visit): Use nonzero rtsize as the condition
for whether to give the node an rtindex or not.
(ffi_type_assign_rtindices): Store the final count as
the rtsize of the root type node. This is then used to
allocate the rtvec for that type in ffi_call_wrap.
-rw-r--r-- | ffi.c | 16 |
1 files changed, 7 insertions, 9 deletions
@@ -944,7 +944,7 @@ static val make_ffi_type_struct(val syntax, val lisp_type, val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops); cnum total_size = 0; cnum most_align = 0; - int rtsize = 0; + int need_in_handler = 0; ft->type = FFI_TYPE_STRUCT; ft->size = 0; @@ -973,15 +973,13 @@ static val make_ffi_type_struct(val syntax, val lisp_type, most_align = align; total_size = (total_size + align - 1) / align * align + size; - rtsize += mtft->rtsize; + need_in_handler = need_in_handler || mtft->rtsize != 0 || mtft->in != 0; } elements[i] = 0; - if (rtsize != 0) { - tft->rtsize = rtsize; + if (need_in_handler) tft->in = ffi_struct_in; - } ft->elements = elements; @@ -1027,10 +1025,8 @@ static val make_ffi_type_array(val syntax, val lisp_type, if (i == 0) { tft->size = etft->size * nelem; tft->align = etft->align; - if (etft->rtsize != 0) { - tft->rtsize = etft->rtsize * nelem; + if (etft->rtsize != 0 || etft->in != 0) tft->in = ffi_array_in; - } } } @@ -1263,14 +1259,16 @@ val ffi_type_compile(val syntax) static void assign_rtindices_visit(struct txr_ffi_type *tft, mem_t *ctx) { int *counter = coerce(int *, ctx); - if (tft->in != 0) + if (tft->rtsize != 0) tft->rtidx = (*counter)++; } static void ffi_type_assign_rtindices(val type) { + struct txr_ffi_type *tft = ffi_type_struct(type); int counter = 0; ffi_type_walk(type, coerce(mem_t *, &counter), assign_rtindices_visit); + tft->rtsize = counter; } val ffi_type_compile_toplevel(val syntax) |