aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/module.c14
-rw-r--r--core/module.h3
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. */