From 1866963738cbefa801d91b73ab140388e50da4a7 Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Sat, 22 Jul 2023 22:30:07 +0200 Subject: [PATCH] gc: Add blockstats --- src/builtins.c | 5 ++++- src/gc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/gc.h | 1 + 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/builtins.c b/src/builtins.c index f48a559..cbcbc9a 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -405,6 +405,9 @@ impl_gc(apfl_ctx ctx) TRY_FORMAT(ctx, apfl_gc_debug_dump_graph(&ctx->gc, w)); } else if (apfl_string_eq(sv, "collect")) { apfl_gc_full(&ctx->gc); + } else if (apfl_string_eq(sv, "blockstats")) { + struct apfl_io_writer w = apfl_get_output_writer(ctx); + TRY_FORMAT(ctx, apfl_gc_debug_blockstats(&ctx->gc, w)); } else { apfl_raise_const_error(ctx, "Unknown gc command"); } @@ -484,7 +487,7 @@ impl_fopen(apfl_ctx ctx) if (argc > 1) { apfl_get_list_member_by_index(ctx, 0, 1); } else { - apfl_push_const_string(ctx, "rb"); + apfl_push_const_string(ctx," rb"); } const char *mode = getcstring(ctx, -1); diff --git a/src/gc.c b/src/gc.c index 1213978..46f88f5 100644 --- a/src/gc.c +++ b/src/gc.c @@ -650,6 +650,56 @@ apfl_gc_debug_dump_graph(struct gc *gc, struct apfl_io_writer w) return true; } +typedef size_t statuscounts[4]; + +static bool +blockstat_line(struct apfl_io_writer w, size_t i, statuscounts counts) +{ + FMT_TRY(apfl_format_put_int(w, (int)i)); + FMT_TRY(apfl_io_write_byte(w, '\t')); + FMT_TRY(apfl_format_put_int(w, (int)counts[GC_STATUS_FREE])); + FMT_TRY(apfl_io_write_byte(w, '\t')); + FMT_TRY(apfl_format_put_int(w, (int)counts[GC_STATUS_BLACK])); + FMT_TRY(apfl_io_write_byte(w, '\t')); + FMT_TRY(apfl_format_put_int(w, (int)counts[GC_STATUS_GREY])); + FMT_TRY(apfl_io_write_byte(w, '\t')); + FMT_TRY(apfl_format_put_int(w, (int)counts[GC_STATUS_WHITE])); + FMT_TRY(apfl_io_write_byte(w, '\n')); + + return true; +} + +bool +apfl_gc_debug_blockstats(struct gc *gc, struct apfl_io_writer w) +{ + statuscounts total = {0, 0, 0, 0}; + size_t i = 0; + + FMT_TRY(apfl_io_write_string(w, "block#\tfree\tblack\tgrey\twhite\n========================================\n")); + + for ( + struct gc_block *cur = gc->block; + cur != NULL; + cur = cur->next + ) { + statuscounts block = {0, 0, 0, 0}; + + for (size_t j = 0; j < GC_OBJECTS_PER_BLOCK; j++) { + enum gc_status status = cur->objects[j].status; + block[status]++; + total[status]++; + } + + FMT_TRY(blockstat_line(w, i, block)); + i++; + } + + FMT_TRY(apfl_io_write_string(w, "========================================\n")); + FMT_TRY(blockstat_line(w, i, total)); + + return true; +} + void apfl_gc_deinit(struct gc *gc) { diff --git a/src/gc.h b/src/gc.h index 5beb2ac..ec8b350 100644 --- a/src/gc.h +++ b/src/gc.h @@ -73,6 +73,7 @@ void apfl_gc_init(struct gc *, struct apfl_allocator, gc_roots_getter, void *roo void apfl_gc_deinit(struct gc *); bool apfl_gc_debug_dump_graph(struct gc *, struct apfl_io_writer); +bool apfl_gc_debug_blockstats(struct gc *, struct apfl_io_writer); size_t apfl_gc_tmproots_begin(struct gc *gc); void apfl_gc_tmproots_restore(struct gc *gc, size_t);