diff options
| author | 2026-10-15 00:09:49 +0330 | |
|---|---|---|
| committer | 2026-10-15 00:09:49 +0330 | |
| commit | 684f40056c4d3dc7a586240d51294b167c9d0ddc (patch) | |
| tree | dfb7142823b5b68406300c1f384b9f33c439fa0b | |
| parent | destructors: heap(v), drop(v, f) / v.drop(f) / v.drop = f, struct drop method... (diff) | |
rt: the free paths take one F_HASDROP test, and dropfree does the drop and the clearing out of line
| -rw-r--r-- | src/runtime/rt.zc | 8 |
1 files changed, 4 insertions, 4 deletions
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); |
