fix(memhub): checkpoint 记录栈初始容量 64K→2M + realloc 失败诊断

单文件翻译(parse AST + 生成 IR)可产生几十万次 alloc,64K 初始容量
在首个大文件就触发 realloc 扩容;realloc 失败时该块不再记录到
checkpoint 栈 → reset_to 无法回收 → 渐进泄漏 → 1GB 主池 OOM
(NewAstTest Phase2 Phase A 根因,used 精确到 2^30 吻合)。

初始容量加大到 2M 条目(16MB stdlib,惰性分配)覆盖单文件峰值,
避免扩容;realloc 失败分支打印 cap/depth 诊断(fail-fast 暴露而非
静默泄漏)。
This commit is contained in:
TermiNexus committed 2026-08-14 18:13:29 +08:00
1 parent 50795b63f1
commit 31d7602368
1 file changed
+15 -7
+15 -7
View File
@@ -362,14 +362,15 @@ class MemBuddy(MemManager):
def mark(self) -> t.CSizeT:
"""返回当前分配水位(checkpoint)
记录栈用 stdlib.malloc 分配(64K 条目 × 8B = 512KB,独立于 buddy 区),
首次调用时懒分配。这样不占用 buddy 池、不会把 1GB 池砍半、
reset_to 也不会误释放栈自身。
记录栈用 stdlib.malloc 分配(独立于 buddy 区,避免占用 buddy 池、
避免 reset_to 误释放栈自身,也避免栈内存与 buddy 块重叠)。
初始容量 2M 条目(16MB):单文件翻译(parse AST + 生成 IR)可产生
几十万次 alloc,64K 初始容量会在首个大文件就触发 realloc 扩容,
扩容失败时块不再记录 → reset_to 永久 no-op → 所有分配泄漏 →
1GB 主池 OOM(NewAstTest Phase2 根因)。
"""
if self.chk_stack is None:
# 记录栈用 stdlib.malloc 分配(独立于 buddy 区,避免占用 buddy 池、
# 避免 reset_to 误释放栈自身,也避免栈内存与 buddy 块重叠)。
cap: t.CSizeT = 64 * 1024
cap: t.CSizeT = 2 * 1024 * 1024
base: t.CVoid | t.CPtr = t.CVoid(stdlib.malloc(cap * 8), t.CPtr)
if base is None:
return 0
@@ -552,7 +553,7 @@ class MemBuddy(MemManager):
c.DerefAs(t.CVoid(t.CUInt64T(block) + bs - MEMBUDDY_CANARY, t.CPtr),
t.CVoid(_canary_pattern(), t.CPtr))
# 记录到 checkpoint 栈(供 reset_to 回收)
# 栈满时 stdlib.realloc 翻倍扩容(防 64K 爆满后记录缺失
# 栈满时 stdlib.realloc 翻倍扩容(防爆满后记录缺失
# → reset 不回收 + _is_valid_ptr 栈校验退化的连锁问题)
if self.chk_stack is not None:
if self.chk_depth >= self.chk_cap:
@@ -563,6 +564,12 @@ class MemBuddy(MemManager):
self.chk_base = new_stack
self.chk_stack = (t.CUInt64T | t.CPtr)(t.CVoid(new_stack, t.CPtr))
self.chk_cap = new_cap
else:
# realloc 失败:块不再记录 → reset_to 无法回收该块 →
# 渐进泄漏最终 1GB 主池 OOM。fail-fast 暴露而非静默。
stdio.printf(
"[MEM] 记录栈 realloc 失败 cap=%zu depth=%zu(reset 将失效,终止)\n",
self.chk_cap, self.chk_depth)
if self.chk_depth < self.chk_cap:
self.chk_stack[self.chk_depth] = t.CUInt64T(block)
self.chk_depth += 1
@@ -752,3 +759,4 @@ class MemBuddy(MemManager):
return 6
ci += 1
return 0