From 684f40056c4d3dc7a586240d51294b167c9d0ddc Mon Sep 17 00:00:00 2001 From: zinc Date: Thu, 15 Oct 2026 00:09:49 +0330 Subject: rt: the free paths take one F_HASDROP test, and dropfree does the drop and the clearing out of line --- src/runtime/rt.zc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/runtime/rt.zc') diff --git a/src/runtime/rt.zc b/src/runtime/rt.zc index afff233..968be87 100644 --- a/src/runtime/rt.zc +++ b/src/runtime/rt.zc @@ -828,7 +828,7 @@ int paylen(word p) { return p[-4] >> 32; } // frees p and, recursively, every object p owns. the block stays quarantined. int release(word p) { word b = p - HDR; int n, i = 0; word w; - if (b[1] & F_HASDROP) dropnow(p); + if (b[1] & F_HASDROP) dropfree(p); n = paylen(p); b[1] = (b[1] & ~7) | 2; // going: not live, and not free yet either, so a child's buddy check can't merge into it while (i < n) { @@ -837,7 +837,6 @@ int release(word p) { w = p[i]; if (isobj(w) && !(w[-4] & F_SHARE) && w[-2] == p) release(w); i++; } - if (b[1] & F_HASDROP) dclear(p); b[1] = b[1] & 2097144; // quarantined (flags but the state, and the class; n is cleared, so len is 0 and indexing traps). the check word and the bytes stay; the next sweep reclaims it return 0; } @@ -871,7 +870,7 @@ unchecked int recycle(.d p) { } if (!isobj(p) || (p[-4] & F_SHARE)) return 0; b = p - HDR; - if (b[1] & F_HASDROP) dropnow(p); + if (b[1] & F_HASDROP) dropfree(p); n = paylen(p); b[1] = (b[1] & ~7) | 2; while (i < n) { @@ -880,7 +879,6 @@ unchecked int recycle(.d p) { w = p[i]; if (isobj(w) && !(w[-4] & F_SHARE) && w[-2] == p) recycle(w); i++; } - if (b[1] & F_HASDROP) dclear(p); if (dbg & 2) fill_w(p, 57005, n); bdrop(b); return 0; @@ -987,6 +985,8 @@ int dropnow(word p) { if (g) { g = g - 1; g(p); } return 0; } +// the free paths' one test leads here: run the drop while p is live, then forget it +int dropfree(word p) { dropnow(p); dclear(p); return 0; } // p's block is going back: forget its entry and bits, so a reused address has no drop int dclear(word p) { int i = dfind(p); -- cgit v1.2.3