diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/runtime/rt.zc | 27 |
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; } |
