aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 16:07:57 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 16:07:57 +0330
commit26f40bc49707a9ff63bee959cf0cd957355e82ce (patch)
tree291aebfe761dcdbc15e957e0d422bf21d6b9b09a /src/runtime
parentmerge: seven self-hosted compiler fixes from conformance (diff)
parentmemdebug: obj_base finds the header from the buddy size classes, not a 64-wor... (diff)
merge: memdebug obj_base via size classes
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/rt.zc27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/runtime/rt.zc b/src/runtime/rt.zc
index 4e52cb5..b468f2a 100644
--- a/src/runtime/rt.zc
+++ b/src/runtime/rt.zc
@@ -1315,7 +1315,7 @@ int scrub() {
// dbg bits: 1 header checks and allocation sites, 2 poison the payload on free
// (the word 57005, which is 0xDEAD), 4 interior pointers keep a quarantined
-// block (the mark walks back at most 64 words to a real header). off unless
+// block (obj_base finds its header from the size classes). off unless
// a program requests. sites are p ^ MAGIC so the collector does not treat them as pointers.
const int NSITE = 64;
@@ -1324,17 +1324,26 @@ int site_drop;
word[64] site_p; word[64] site_line;
// true when p is a freed block still held in quarantine.
word quar(word p) { return p >= HEAP_LO + HDR && p < hbump && p[-3] == (p ^ MAGIC) && !(p[-4] & 1); }
-// the object whose payload contains w, or 0. exact pointers and interiors.
+// the object whose payload contains w, or 0. exact pointers and interiors, at any
+// depth. every block of class k starts at HEAP_LO plus a multiple of 2^k words, so
+// the block holding w, if any, starts at w rounded down to one of those. the
+// candidates are tried from the largest class down: a header counts only when its
+// check word, size and class agree with k, and the first that holds w in its
+// payload is the block. a merge clears the upper half's header and a split rewrites
+// the header at the same address, so a stale header can only sit inside the
+// payload of the real block, which is found first.
word obj_base(int w) {
- int i = 0; word p; int n;
+ int k = 31, off, sz; word b, p;
if (w < HEAP_LO + HDR || w >= hbump) return 0;
- while (i <= 64) {
- p = w - i;
- if (p >= HEAP_LO + HDR && p < hbump && p[-3] == (p ^ MAGIC)) {
- n = p[-5] - HDR;
- if (w >= p && w < p + n) return p;
+ off = w - HEAP_LO;
+ while (k >= 3) {
+ sz = pow2[k];
+ b = HEAP_LO + off - off % sz;
+ p = b + HDR;
+ if (sz <= hbump - HEAP_LO && p < hbump && b[0] == sz && p[-3] == (p ^ MAGIC) && bclass(b) == k) {
+ if (w >= p && w < b + sz) return p;
}
- i++;
+ k--;
}
return 0;
}