summaryrefslogtreecommitdiff
path: root/pez.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-10-10 15:34:39 +0200
committerlemon <lsof@mailbox.org>2022-10-10 15:34:39 +0200
commit113ca8ba774006c1d24bc399dd42756cc3239bf6 (patch)
tree30e5fce910ffda4f3572c3d98576251607844019 /pez.c
parentedec4da0983cf9dc7bae487598ada734c21ea60e (diff)
cache closures with no upvalues
Diffstat (limited to 'pez.c')
-rw-r--r--pez.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/pez.c b/pez.c
index 93b9354..19d53ce 100644
--- a/pez.c
+++ b/pez.c
@@ -76,7 +76,10 @@ typedef struct Proto {
const char *file;
const uint8_t *code;
const Val *con;
- struct cmupval *upval;
+ union {
+ struct cmupval *upval;
+ struct Fn *fn0; /* closures with 0 upvalues are cached */
+ };
char name[];
} Proto;
@@ -471,7 +474,9 @@ delproto(PezContext *cx, Proto *pr)
{
cxfree(cx, (void *)pr->code, pr->ncode);
cxfree(cx, (void *)pr->con, pr->ncon * sizeof(Val));
- cxfree(cx, (void *)pr->upval, pr->nupval * sizeof(struct cmupval));
+ if (pr->nupval) {
+ cxfree(cx, (void *)pr->upval, pr->nupval * sizeof(struct cmupval));
+ }
}
static void
@@ -503,7 +508,11 @@ sizeoffn(Fn *fn)
static Fn *
newfn(PezContext *cx, Proto *pr, Val *args, Val *locals, Fn *parent)
{
- Fn *fn = newobj(cx, PEZ_TFn, sizeof *fn + pr->nupval * sizeof(struct Upval *));
+ Fn *fn;
+ if (pr->nupval == 0 && pr->fn0) {
+ return pr->fn0;
+ }
+ fn = newobj(cx, PEZ_TFn, sizeof *fn + pr->nupval * sizeof(struct Upval *));
if (fn) {
TRY(push(cx, box_obj(fn))); // gc keep
fn->proto = pr;
@@ -537,6 +546,9 @@ newfn(PezContext *cx, Proto *pr, Val *args, Val *locals, Fn *parent)
}
pop(cx);
}
+ if (pr->nupval == 0) {
+ pr->fn0 = fn;
+ }
return fn;
}
@@ -1979,7 +1991,7 @@ f_arrayfill(PezContext *cx, int argc)
n = unbox_num(cx->stktop[-2]);
if (!isnum(cx->stktop[-2]) || n < 0 || fixtrunc(n) != n) {
pez_error(cx, "array#fill", "argument #1 should be positive integer");
- return 0;
+ return 0;
}
TRY(arr = newarr(cx, fixtoint(n)));
arr->len = fixtoint(n);
@@ -2054,10 +2066,9 @@ fincompfn(Comp *cm)
pr->ncode = cm->code.len;
pr->con = con;
pr->ncon = cm->con.len;
- pr->upval = cxalloc(cm->cx, cm->fenv.nupval * sizeof *pr->upval);
- pr->nupval = cm->fenv.nupval;
- // fprintf(stderr, "fini %s %d\n", pr->name, pr->nupval);
- if (pr->upval) {
+ pr->upval = NULL;
+ if ((pr->nupval = cm->fenv.nupval) != 0) {
+ pr->upval = cxalloc(cm->cx, cm->fenv.nupval * sizeof *pr->upval);
memcpy(pr->upval, cm->fenv.upvals, pr->nupval * sizeof(struct cmupval));
}
memset(&cm->code, 0, sizeof cm->code);