summaryrefslogtreecommitdiffstats
path: root/struct.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-08-27 07:09:14 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-08-27 07:09:14 -0700
commit502299dafb9307345bfb455f52997e1c9be6f12c (patch)
tree4062f207acea25f11612b5d0c98c5186204845fb /struct.c
parentd990b667b33d853fcce6294364ae4232545742b0 (diff)
downloadtxr-502299dafb9307345bfb455f52997e1c9be6f12c.tar.gz
txr-502299dafb9307345bfb455f52997e1c9be6f12c.tar.bz2
txr-502299dafb9307345bfb455f52997e1c9be6f12c.zip
OOP: optimization in dupe base check.
Hypothesis: the majority of struct types will not be used as inheritance bases, and most of those that are bases will not be appear as duplicate bases. If we put a flag into a type which indicates that it has been used as a duplicate base, we can check that flag to do less work when initializing an object. * struct.c (struct struct_type): New flag, dupe. (get_duplicate_supers): Each time we find a duplicate supertype, we set its dupe flag. (make_struct_type): Allocate the struct type with chk_calloc instead of chk_malloc, so the flag is initialized to zero. Remove initializations of some members to zero: those of nslots, ntslots, stslot and spslot. (call_initfun_chain, call_postinitfun_chain): Don't bother search for st in the root's array of duplicates if st is not marked with the dupe flag.
Diffstat (limited to 'struct.c')
-rw-r--r--struct.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/struct.c b/struct.c
index 5564f3c4..04b5ee7d 100644
--- a/struct.c
+++ b/struct.c
@@ -91,6 +91,7 @@ struct struct_type {
val dvtypes;
struct stslot *stslot;
struct stslot **spslot;
+ unsigned dupe : 1;
};
struct struct_inst {
@@ -335,8 +336,10 @@ static val get_duplicate_supers(val supers, val self)
ucnum mask = (ucnum) 1 << pos;
if ((mask & bloom) != 0) {
- if (memq(super, all_supers) != iter && !memq(super, dup_supers))
+ if (memq(super, all_supers) != iter && !memq(super, dup_supers)) {
ptail = list_collect(ptail, super);
+ st->dupe = 1;
+ }
}
bloom |= mask;
@@ -443,7 +446,7 @@ val make_struct_type(val name, val supers,
self, nao);
} else {
struct struct_type *st = coerce(struct struct_type *,
- chk_malloc(sizeof *st));
+ chk_calloc(1, sizeof *st));
val dup_supers = if3(opt_compat && opt_compat <= 242,
nil, get_duplicate_supers(supers, self));
cnum nsupers = c_num(length(supers), self);
@@ -464,12 +467,10 @@ val make_struct_type(val name, val supers,
st->self = stype;
st->name = name;
st->id = c_num(id, self);
- st->nslots = st->nstslots = 0;
st->slots = all_slots;
st->nsupers = nsupers;
st->ndsupers = ndsupers;
st->supers = supers;
- st->stslot = 0;
st->sus = sus;
st->dsus = dsus;
st->stinitfun = static_initfun;
@@ -477,7 +478,6 @@ val make_struct_type(val name, val supers,
st->boactor = boactor;
st->postinitfun = default_null_arg(postinitfun);
st->dvtypes = nil;
- st->spslot = 0;
gc_finalize(stype, struct_type_finalize_f, nil);
@@ -676,7 +676,7 @@ static void call_initfun_chain(struct struct_type *st, val strct,
if (st) {
cnum i;
- if (st != root)
+ if (st != root && st->dupe)
for (i = 0; i < root->ndsupers; i++) {
if (st == root->dsus[i]) {
const int bits_ucnum = sizeof *seen * CHAR_BIT;
@@ -703,7 +703,7 @@ static void call_postinitfun_chain(struct struct_type *st, val strct,
int derived_first = (opt_compat && opt_compat <= 148);
cnum i;
- if (st != root)
+ if (st != root && st->dupe)
for (i = 0; i < root->ndsupers; i++) {
if (st == root->dsus[i]) {
const int bits_ucnum = sizeof *seen * CHAR_BIT;