This commit is contained in:
2026-02-13 05:03:45 -06:00
parent 9f0fd84f4f
commit 0a680a0cd3

View File

@@ -728,10 +728,16 @@ void *js_malloc (JSContext *ctx, size_t size) {
The second GC is cheap: data was just compacted so there is
almost no garbage to skip. */
if ((uint8_t *)ctx->heap_free + size > (uint8_t *)ctx->heap_end) {
size_t need = (size_t)((uint8_t *)ctx->heap_free - (uint8_t *)ctx->heap_base) + size;
size_t live = (size_t)((uint8_t *)ctx->heap_free - (uint8_t *)ctx->heap_base);
size_t need = live + size;
size_t ns = ctx->current_block_size;
while (ns < need && ns < (1ULL << BUDDY_MAX_ORDER))
ns *= 2;
#ifdef DUMP_GC
printf (" growing %zu -> %zu for %zu byte alloc (live %zu)\n",
ctx->current_block_size, ns, size, live);
fflush (stdout);
#endif
ctx->next_block_size = ns;
if (ctx_gc (ctx, 1, size) < 0) {
JS_ThrowOutOfMemory (ctx);
@@ -1332,7 +1338,7 @@ int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) {
#ifdef DUMP_GC
int will_grow = 0;
#endif
if (allow_grow && old_used > 0 && recovered < old_used / 5) {
if (allow_grow && recovered > 0 && old_used > 0 && recovered < old_used / 5) {
size_t doubled = new_size * 2;
if (doubled <= (1ULL << BUDDY_MAX_ORDER)) {
ctx->next_block_size = doubled;
@@ -1343,15 +1349,42 @@ int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) {
}
#ifdef DUMP_GC
printf ("\nGC: %zu -> %zu bytes (used %zu -> %zu), recovered %zu (%.1f%%)%s\n",
old_heap_size,
new_size,
old_used,
new_used,
recovered,
old_used > 0 ? (recovered * 100.0 / old_used) : 0.0,
will_grow ? ", heap will grow" : "");
fflush(stdout);
{
/* Walk to-space and tally memory by object type */
static const char *type_names[] = {
[OBJ_ARRAY] = "array",
[OBJ_TEXT] = "text",
[OBJ_RECORD] = "record",
[OBJ_FUNCTION] = "function",
[OBJ_FRAME] = "frame",
};
size_t type_bytes[8] = {0};
size_t type_count[8] = {0};
uint8_t *p = to_base;
while (p < to_free) {
uint8_t t = objhdr_type (*(objhdr_t *)p);
size_t sz = gc_object_size (p);
type_bytes[t] += sz;
type_count[t]++;
p += sz;
}
printf ("\nGC: %zu -> %zu bytes, recovered %zu (%.1f%%)%s\n",
old_heap_size,
new_size,
recovered,
old_used > 0 ? (recovered * 100.0 / old_used) : 0.0,
will_grow ? ", will grow (poor recovery)" : "");
printf (" live %zu / %zu bytes (%.0f%% full):",
new_used, new_size,
new_size > 0 ? (new_used * 100.0 / new_size) : 0.0);
for (int i = 0; i < 7; i++) {
if (type_count[i] == 0) continue;
printf (" %s %zu(%zu)", type_names[i], type_bytes[i], type_count[i]);
}
printf ("\n");
fflush (stdout);
}
#endif
return 0;