fence (25.1c): the census reads the heap outside Ludic's blocks; blocks counted at malloc's own size

The census's native line is malloc's live bytes over every zone since judging began less what
Ludic's tracked blocks kept - the libraries' and drivers' growth, read before the census file is
opened. A tracked block counts malloc_size(), not the size asked for, so kept is what the heap pays
and the residual carries no rounding. @malloc_zone_statistics is declared once, by the fence or by
Os.heap_bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-28 15:38:13 +03:00
parent a8d54e9878
commit 691964877b
7 changed files with 47519 additions and 47279 deletions

View file

@ -33,6 +33,7 @@ function emit_fence_globals() -> void {
emith("@lp_fkept = global i64 0\n")
emith("@lp_fbad = global i64 0\n")
emith("@lp_fjudged = global i64 0\n")
emith("@lp_zset = global i64 0\n")
emith("@lp_census = global ptr null\n")
emith("declare extern_weak i64 @malloc_size(ptr)\n")
emith("declare i32 @dprintf(i32, ptr, ...)\n")
@ -58,6 +59,7 @@ function emit_fence_globals() -> void {
emith("@.lpf_auto = private unnamed_addr constant [15 x i8] c\"R3D_ALLOC_AUTO\\00\"\n")
emith("@.lpf_w = private unnamed_addr constant [2 x i8] c\"w\\00\"\n")
emith("@.lpf_chdr = private unnamed_addr constant [76 x i8] c\"alloc-census frames %lld bad %lld kept %lld made %lld freed %lld over %lld\\0A\\00\"\n")
emith("@.lpf_cnat = private unnamed_addr constant [91 x i8] c\"native %lld (the heap outside Ludic's blocks, since judging began: libraries and drivers)\\0A\\00\"\n")
emith("@.lpf_crow = private unnamed_addr constant [23 x i8] c\"site %lld %s %s:%d %s\\0A\\00\"\n")
emith("@.lpf_from = private unnamed_addr constant [15 x i8] c\" from %s\\0A\\00\"\n")
emith("@.lpf_cfrom = private unnamed_addr constant [11 x i8] c\" from %s\\0A\\00\"\n")
@ -277,11 +279,18 @@ function emit_fence_table() -> void {
emith("out:\n")
emith(" ret void\n")
emith("}\n")
emith("define internal void @lp_fadd(ptr %p, i64 %n) {\n")
emith("define internal void @lp_fadd(ptr %p, i64 %asked) {\n")
emith("entry:\n")
emith(" %isnull = icmp eq ptr %p, null\n")
emith(" br i1 %isnull, label %out, label %go\n")
emith(" br i1 %isnull, label %out, label %size\n")
emith("size:\n")
emith(" %hasms = icmp ne ptr @malloc_size, null\n")
emith(" br i1 %hasms, label %real, label %go\n")
emith("real:\n")
emith(" %ms = call i64 @malloc_size(ptr %p)\n")
emith(" br label %go\n")
emith("go:\n")
emith(" %n = phi i64 [ %asked, %size ], [ %ms, %real ]\n")
emith(" call void @lp_flock()\n")
emith(" %cnt = load i64, ptr @lp_tabn\n")
emith(" %max = load i64, ptr @lp_tabmax\n")
@ -749,6 +758,7 @@ function emit_fence_report() -> void {
emith(" %none = icmp eq ptr %path, null\n")
emith(" br i1 %none, label %out, label %open\n")
emith("open:\n")
emith(" %zn = call i64 @lp_fzone()\n")
emith(" %fp = call ptr @fopen(ptr %path, ptr @.lpf_w)\n")
emith(" %bad = icmp eq ptr %fp, null\n")
emith(" br i1 %bad, label %out, label %write\n")
@ -761,6 +771,12 @@ function emit_fence_report() -> void {
emith(" %fr = load i64, ptr @lp_freed\n")
emith(" %ov = load i64, ptr @lp_over\n")
emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_chdr, i64 %j, i64 %b, i64 %k, i64 %md, i64 %fr, i64 %ov)\n")
emith(" %jq = icmp ne i64 %j, 0\n")
emith(" %zs = load i64, ptr @lp_zset\n")
emith(" %zd = sub i64 %zn, %zs\n")
emith(" %nat = sub i64 %zd, %k\n")
emith(" %nat1 = select i1 %jq, i64 %nat, i64 0\n")
emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_cnat, i64 %nat1)\n")
emith(" %sn = load i32, ptr @lp_site_n\n")
emith(" call void @lp_franked(ptr %fp, ptr @lp_site_base, i1 1, i32 %sn, i32 40)\n")
emith(" call i32 @fclose(ptr %fp)\n")
@ -797,6 +813,20 @@ function emit_fence_frame() -> void {
emith(" call void @lp_fsnap()\n")
emith(" ret void\n")
emith("}\n")
emith("; malloc's live bytes over every zone (0 where there is no malloc_zone_statistics)\n")
emith("define internal i64 @lp_fzone() {\n")
emith("entry:\n")
emith(" %has = icmp ne ptr @malloc_zone_statistics, null\n")
emith(" br i1 %has, label %read, label %none\n")
emith("none:\n")
emith(" ret i64 0\n")
emith("read:\n")
emith(" %st = alloca [4 x i64], align 8\n")
emith(" call void @malloc_zone_statistics(ptr null, ptr %st)\n")
emith(" %p = getelementptr [4 x i64], ptr %st, i32 0, i32 1\n")
emith(" %n = load i64, ptr %p\n")
emith(" ret i64 %n\n")
emith("}\n")
emith("define internal void @lp_fsettle_locked() {\n")
emith("entry:\n")
emith(" %n = load i32, ptr @lp_site_n\n")
@ -807,6 +837,8 @@ function emit_fence_frame() -> void {
emith(" store i64 %lv, ptr @lp_slive\n")
emith(" %pr = load i64, ptr @lp_pre\n")
emith(" store i64 %pr, ptr @lp_spre\n")
emith(" %z = call i64 @lp_fzone()\n")
emith(" store i64 %z, ptr @lp_zset\n")
emith(" store i8 1, ptr @lp_fj\n")
emith(" ret void\n")
emith("}\n")