diff options
| -rw-r--r-- | core/module.c | 14 | ||||
| -rw-r--r-- | core/module.h | 3 |
2 files changed, 12 insertions, 5 deletions
diff --git a/core/module.c b/core/module.c index cbf0efe..ac46fb3 100644 --- a/core/module.c +++ b/core/module.c @@ -2728,13 +2728,12 @@ static void clear_rows(PureApp *app) { void pure_app_memory(PureApp *app, size_t bytes) { app->memory = bytes; } size_t pure_app_state_bytes(const PureApp *app) { - const PureModule *m = app->module; size_t bytes = (app->outbox ? pure_list_size(app->outbox) : 0) + (app->heard ? pure_list_size(app->heard) : 0); - for (uint32_t i = 0; i < m->states; ++i) { - if (app->lists[i] && !(m->state_flags[i] & PURE_LIST_ROWS >> 8)) bytes += pure_list_size(app->lists[i]); - else if (app->texts[i]) bytes += pure_draft_size(app->texts[i]); + for (uint32_t left = app->counted; left; left &= left - 1) { + unsigned i = (unsigned)__builtin_ctz(left); + bytes += app->lists[i] ? pure_list_size(app->lists[i]) : app->texts[i] ? pure_draft_size(app->texts[i]) : 0; } - return bytes; /* a message's rows are its own, gone when it ends */ + return bytes; } /* One event: every handler for it runs in module order against pending @@ -3550,6 +3549,11 @@ PURE_COLD static PureResult open_module(PureApp *app, const PureModule *module) if (old) remap_outputs(app, old, module, true); drop_passes(app); /* kept by instruction of the module they were made for */ app->module = module; + app->counted = 0; + for (uint32_t i = 0; i < module->states; ++i) + if (module->state_type[i] == PURE_STATE_TEXT || + (module->state_type[i] == PURE_STATE_LIST && !(module->state_flags[i] & PURE_LIST_ROWS >> 8))) + app->counted |= UINT32_C(1) << i; /* a message's rows are its own, gone when it ends */ ++app->changes; return PURE_OK; } diff --git a/core/module.h b/core/module.h index c11c682..69acd67 100644 --- a/core/module.h +++ b/core/module.h @@ -157,6 +157,8 @@ typedef struct { uint8_t form, relation; uint16_t field; uint32_t test; PureBloc enum { PURE_MODULE_RANGES = 64 }; typedef struct { uint8_t lower_relation, upper_relation; PureBlock lower, upper; } PureRange; +_Static_assert(PURE_MODULE_STATES <= 32, "a state is a bit of PureApp.counted"); + typedef struct { uint16_t states, inputs, views, handlers, fields, collections, constants, records, record_fields; uint32_t code_count; @@ -313,6 +315,7 @@ typedef struct { PureFault fault; uint32_t fault_pc; size_t memory; /* the budget of what the states hold (0: none): pure_app_memory */ + uint32_t counted; /* the states it counts, a bit each: lists (not a message's rows) and texts */ uint64_t ticks, events; /* The time events see as now, in milliseconds since 1970 (UTC). The host * sets it, so a script can replay any time; views never see it. */ |
