summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-28 22:52:48 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-28 22:52:48 -0700
commitc023a09e3faeef479ba866445a7a346b8e9c3f8a (patch)
treef819b764f7a41d92361fd3bec5ea843cd1164215
parente5174a9dac601791af64903f44b8ab4a5e82621e (diff)
downloadtxr-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.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/ffi.c b/ffi.c
index c4aa17e6..7a667486 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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)