From 1ef9dd24773058f766ad80ffc7a59295fc44c92d Mon Sep 17 00:00:00 2001 From: eunhhu Date: Mon, 5 Oct 2026 08:41:45 +0100 Subject: Compile only blocks with a loop, keep no code for a module without one, set a frame's fields one by one, and inline group_of (021) - Compiled code paid only where blocks repeat; a block run once (a view's cell, a fold's item, most handlers) ran slower through the code's entry and its calls of step: the bank's table queries took 16-24% more instructions. Now only a block with an EACH or a LOOP is compiled, and a module with none keeps no compiled code. - run() set its whole frame each time (the compiled code's run among it); now its fields one by one. - group_of is inlined into its pass: after the executor's refactor it was a call per row (per_branch +4-5% instructions; now +1.1-1.3%). --- core/module.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'core/module.c') diff --git a/core/module.c b/core/module.c index c486d45..8771cab 100644 --- a/core/module.c +++ b/core/module.c @@ -2294,7 +2294,7 @@ static size_t group_slot(uint64_t bits, size_t capacity) { } /* key's group, added when absent (with add); NULL when absent, or without room. */ -static Group *group_of(struct PurePass *pass, double key, unsigned how, bool add) { +static inline __attribute__((always_inline)) Group *group_of(struct PurePass *pass, double key, unsigned how, bool add) { key = key == 0 ? 0 : key; if (pass->capacity) { for (size_t at = group_slot(order_bits(key), pass->capacity);; at = (at + 1) & (pass->capacity - 1)) { @@ -3071,13 +3071,24 @@ int pure_run_iterate(Frame *frame) { return how != STEP_NEXT ? how : next != UINT32_MAX ? STEP_NEXT : STEP_DONE; } +/* A frame for block, its fields set one by one: a block runs often (a + * fold's item, a view's cell), and filling the whole frame each time (the + * compiled code's run among it) costs more than the block. */ +static inline __attribute__((always_inline)) void open_frame(Frame *frame, const PureModule *m, PureValue *values, PureBlock block, + Event *ev, Slot *stack, Loop *loops) { + frame->m = m, frame->values = values, frame->ev = ev, frame->app = ev->app, frame->arena = ev->arena; + frame->stack = stack, frame->sp = 0, frame->loops = loops, frame->depth = 0; + frame->end = block.start + block.length; +} + /* A block run by its compiled code. */ static __attribute__((noinline)) PureResult run_compiled(PureCompiled code, const PureModule *m, PureValue *values, PureBlock block, Event *ev, Slot *result) { Slot stack[PURE_MODULE_STACK]; Loop loops[PURE_MODULE_NESTING]; - Frame frame = {.m = m, .values = values, .ev = ev, .app = ev->app, .arena = ev->arena, .stack = stack, - .end = block.start + block.length, .loops = loops}; + Frame frame; + open_frame(&frame, m, values, block, ev, stack, loops); + frame.run.list = NULL; /* no run kept yet */ return finish(&frame, code(&frame), result); } @@ -3086,8 +3097,8 @@ static PureResult run(const PureModule *m, PureValue *values, PureBlock block, E if (code) return run_compiled(code, m, values, block, ev, result); Slot stack[PURE_MODULE_STACK]; Loop loops[PURE_MODULE_NESTING]; - Frame frame = {.m = m, .values = values, .ev = ev, .app = ev->app, .arena = ev->arena, .stack = stack, - .end = block.start + block.length, .loops = loops}; + Frame frame; + open_frame(&frame, m, values, block, ev, stack, loops); int how = STEP_NEXT; for (uint32_t pc = block.start;;) { if (pc >= frame.end) { /* the block ran; or a loop's ran once: again, or the loop ends (its end may be its outer's) */ -- cgit v1.2.3