From ff2e0823e97d10477341192d72f5d9e61d9d5bad Mon Sep 17 00:00:00 2001 From: eunhhu Date: Sun, 18 Oct 2026 23:29:42 +0100 Subject: 027's 4f-2: no fixed count of states: the header's u16 alone (PURE_MODULE_STATES gone); a module's transient and counted states are flags of each, the lists views and functions change or name sets of states (state_words words, a bit each), the verifier's walked lists a list with its length, duplicate names found by sorting them; an app's eighteen arrays of each state (values, texts, lists, the stored lists' slots, the last save's and the burst's, a reader's, an event's values and marks) in one block sized to its module, a replace laying the new module's apart and taking it once nothing can fail; the runtime's lists placed past any state (PURE_LIST_HEARD 0x10000), their slots after the states'; a snapshot's arrays sized so too; pure_app_read false without room (pure-serve then shows none); a save's drafts, values and the tree's revisions on the stack for 64 states, else on the heap; the JIT compiles modules of 32 states at most (its sets a word), the app's lists read through a pointer; a view reads the app's values as they are (no state changes in one), no copy of 32 a evaluation; unit test: 300 states loaded and the last counted; a hole closed: pure_app_stop read the arrays a failed start never laid; PureApp 4,256 bytes, not 8,504; counts: b39b against b38 with batches within 0.06%, without batches knapsack +0.49%, join +0.23%, the rest within 0.17%; the bank's queries (s38 and s39b in turns, three each) field -1.99%, found -1.18%, in_credit -1.10%, large -0.99%, the rest -0.58% to +0.11% (the first build, s39, copied a view's values at run time's size: in_credit +2.4%); 008 and 027 --- core/module-jit.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'core/module-jit.c') diff --git a/core/module-jit.c b/core/module-jit.c index 5ba9f03..8208095 100644 --- a/core/module-jit.c +++ b/core/module-jit.c @@ -28,6 +28,9 @@ #include #include +/* The states a module it compiles has at most: its sets of lists and states are a word's bits (027's 4f-2). */ +enum { JIT_STATES = 32 }; + struct PureJit { unsigned char *memory; /* the code, executable */ size_t size; @@ -4131,7 +4134,7 @@ static int tlist(Tier *t, TList *lists, unsigned list, unsigned part) { /* What each list access needs, as values where the tier begins: a column (its address tagged with its cells' width), the count, the key bits and their reach. */ static void tier_lists(Tier *t, TList *lists) { - for (unsigned i = 0; i < PURE_MODULE_STATES; ++i) { + for (unsigned i = 0; i < JIT_STATES; ++i) { for (unsigned p = 0; p < L_PARTS; ++p) lists[i].part[p] = -1; lists[i].position = lists[i].key = lists[i].full = false; } @@ -4167,7 +4170,7 @@ static void tier_lists(Tier *t, TList *lists) { } for (size_t i = 0; i < made; ++i) if (t->vals[i].op == T_FIND) lists[t->vals[i].list].full = true; - for (unsigned i = 0; i < PURE_MODULE_STATES; ++i) { /* found by key and by position: DENSE and full, its count its keys' reach */ + for (unsigned i = 0; i < JIT_STATES; ++i) { /* found by key and by position: DENSE and full, its count its keys' reach */ if (lists[i].key && lists[i].position) lists[i].full = true; if (lists[i].full) (void)tlist(t, lists, i, L_COUNT); } @@ -4583,10 +4586,9 @@ static unsigned tbase(Tier *t, unsigned which, unsigned into) { case B_LOCALS: load64(e, into, X19, offsetof(Frame, ev)), load64(e, into, into, offsetof(Event, locals)); break; case B_VALUES: load64(e, into, X19, offsetof(Frame, values)); break; case B_APP: load64(e, into, X19, offsetof(Frame, app)); break; - case B_LISTS: + case B_LISTS: /* the app's lists (an array of them since 027's 4f-2) */ load64(e, into, X19, offsetof(Frame, app)); - mov_imm(e, X10, offsetof(PureApp, lists)); - add_reg(e, into, into, X10); + load64(e, into, into, offsetof(PureApp, lists)); break; case B_LOOPS: load64(e, into, X19, offsetof(Frame, loops)); break; case B_EV: load64(e, into, X19, offsetof(Frame, ev)); break; @@ -4602,8 +4604,7 @@ static void tier_fixed(Tier *t) { load64(e, X21, X19, offsetof(Frame, values)); load64(e, X22, X19, offsetof(Frame, ev)); load64(e, X23, X19, offsetof(Frame, app)); - mov_imm(e, X24, offsetof(PureApp, lists)); - add_reg(e, X24, X23, X24); + load64(e, X24, X23, offsetof(PureApp, lists)); load64(e, X27, X19, offsetof(Frame, loops)); load64(e, X28, X22, offsetof(Event, locals)); } @@ -5354,7 +5355,7 @@ static void tier_emit(Tier *t, int entry, int fallback) { Emit *e = k->e; const LoopAt *l0 = &k->loops[t->nest]; bind(e, entry); - for (unsigned list = 0; list < PURE_MODULE_STATES; ++list) { /* each list as the tier reads it (pure_list_suits) */ + for (unsigned list = 0; list < JIT_STATES; ++list) { /* each list as the tier reads it (pure_list_suits) */ const TList *l = &t->lists[list]; unsigned needs = 0, narrow = 0; for (unsigned f = 0; f < 16; ++f) narrow |= l->part[f] >= 0 ? 1u << f : 0; @@ -5606,7 +5607,7 @@ static Tier *tier_plan(Block *k, unsigned li) { if (!k->loops[l].walk && k->loops[l].at >= l0->at && k->loops[l].end <= l0->end) t->slots |= UINT64_C(1) << (k->m->code[k->loops[l].at].arg & 0x3F); tier_liveness(t); tier_build(t); - if (!t->failed && !(t->lists = calloc(PURE_MODULE_STATES, sizeof(*t->lists)))) t->failed = true; + if (!t->failed && !(t->lists = calloc(JIT_STATES, sizeof(*t->lists)))) t->failed = true; if (!t->failed) tier_lists(t, t->lists); const char *hoist = getenv("PURE_TIER_HOIST"); if (!t->failed && !(hoist && !strcmp(hoist, "0"))) tier_hoist(t); @@ -5656,8 +5657,7 @@ static bool compile_block(const PureModule *m, PureBlock block, unsigned end_hei load64(e, X21, X19, offsetof(Frame, values)); load64(e, X22, X19, offsetof(Frame, ev)); load64(e, X23, X19, offsetof(Frame, app)); - mov_imm(e, X24, offsetof(PureApp, lists)); - add_reg(e, X24, X23, X24); /* the app's lists */ + load64(e, X24, X23, offsetof(PureApp, lists)); /* the app's lists */ load64(e, X27, X19, offsetof(Frame, loops)); load64(e, X28, X22, offsetof(Event, locals)); mov_imm(e, X9, UINT64_C(0x7FF0000000000000)); @@ -5786,7 +5786,9 @@ static bool want(const PureModule *m, PureBlock block, unsigned leaves, Made **m struct PureJit *pure_jit_make(const PureModule *m) { const char *enabled = getenv("PURE_JIT"); - if ((enabled && !strcmp(enabled, "0")) || !m->height || !m->code_count) return NULL; + /* What it makes keeps its lists' and states' sets in a word each: a module of more states runs in the executor + * alone (027's 4f-2). */ + if ((enabled && !strcmp(enabled, "0")) || !m->height || !m->code_count || m->states > JIT_STATES) return NULL; Made *made = NULL; size_t count = 0, room = 0; bool ok = true; -- cgit v1.2.3