fix(KB-9): move Lowering/ProgramIndex maps off page_allocator defaults
16 Lowering map fields and 8 ProgramIndex map fields were declared with `= ....init(std.heap.page_allocator)` field defaults that init() never replaced — every instance really allocated page-at-a-time outside the compilation allocator, invisible to leak checking and never reclaimed. All 24 now init explicitly with the compilation allocator (module.alloc / the init alloc param), which is arena-backed in both the driver (main's arena) and the test suites (per-test arenas), so backing is reclaimed at teardown. ProgramIndex's struct doc no longer claims the page_allocator defaults. Six lower.test.zig tests that constructed Module with bare std.testing.allocator leaked once the checker could finally see these maps; they now use the same per-test ArenaAllocator idiom as the rest of the file and the facade test suites. Gate: zig build OK; zig build test 426/426 (6/6 steps, leak-clean); run_examples 541/0; zero expected/ snapshot churn.
This commit is contained in:
@@ -592,9 +592,9 @@ pub const GlobalInfo = struct { id: inst.GlobalId, ty: TypeId };
|
||||
/// (pointers into maps owned by the compilation driver, `core.zig`) — those are
|
||||
/// read-only views and are never freed here.
|
||||
///
|
||||
/// Per-map allocators are preserved exactly as they were on `Lowering`:
|
||||
/// `import_flags` / `fn_ast_map` / `global_names` use the lowering allocator
|
||||
/// (set in `init`); the rest default to `page_allocator`. Written only by the
|
||||
/// Every owned map allocates through the compilation allocator passed to
|
||||
/// `init` (arena-backed in both the driver and the tests — KB-9 removed the
|
||||
/// old `page_allocator` field defaults). Written only by the
|
||||
/// declaration scan / registration code in `Lowering`; read everywhere else.
|
||||
pub const ProgramIndex = struct {
|
||||
/// The lowering/compilation allocator (`module.alloc`), retained so the
|
||||
@@ -639,27 +639,27 @@ pub const ProgramIndex = struct {
|
||||
/// resolve (issue 0100 F1). Keyed/allocated with the lowering allocator.
|
||||
qualified_fn_source: std.StringHashMap([]const u8),
|
||||
/// sx alias → ForeignClassDecl (jni_class / objc_class / swift_class / ... — registered in scan pass).
|
||||
foreign_class_map: std.StringHashMap(*const ast.ForeignClassDecl) = std.StringHashMap(*const ast.ForeignClassDecl).init(std.heap.page_allocator),
|
||||
foreign_class_map: std.StringHashMap(*const ast.ForeignClassDecl),
|
||||
/// `#run` global name → GlobalId.
|
||||
global_names: std.StringHashMap(GlobalInfo),
|
||||
/// Type alias name → target TypeId. The single-source alias table; passed
|
||||
/// explicitly to `TypeResolver` / `type_bridge` resolution (no borrow).
|
||||
type_alias_map: std.StringHashMap(TypeId) = std.StringHashMap(TypeId).init(std.heap.page_allocator),
|
||||
type_alias_map: std.StringHashMap(TypeId),
|
||||
/// Generic struct name → template.
|
||||
struct_template_map: std.StringHashMap(StructTemplate) = std.StringHashMap(StructTemplate).init(std.heap.page_allocator),
|
||||
struct_template_map: std.StringHashMap(StructTemplate),
|
||||
/// `DeclId` → generic struct template — the DeclId-keyed analogue of
|
||||
/// `struct_template_map`, built in parallel during `registerStructDecl`.
|
||||
/// Nothing reads it for selection yet; `struct_template_map` stays the live
|
||||
/// consumer until the S4 cutover.
|
||||
struct_template_by_decl: std.AutoHashMap(imports.DeclId, StructTemplate) = std.AutoHashMap(imports.DeclId, StructTemplate).init(std.heap.page_allocator),
|
||||
struct_template_by_decl: std.AutoHashMap(imports.DeclId, StructTemplate),
|
||||
/// Protocol name → protocol info.
|
||||
protocol_decl_map: std.StringHashMap(ProtocolDeclInfo) = std.StringHashMap(ProtocolDeclInfo).init(std.heap.page_allocator),
|
||||
protocol_decl_map: std.StringHashMap(ProtocolDeclInfo),
|
||||
/// Protocol name → AST node.
|
||||
protocol_ast_map: std.StringHashMap(*const ast.ProtocolDecl) = std.StringHashMap(*const ast.ProtocolDecl).init(std.heap.page_allocator),
|
||||
protocol_ast_map: std.StringHashMap(*const ast.ProtocolDecl),
|
||||
/// Module-level value constants (e.g. AF_INET :s32: 2).
|
||||
module_const_map: std.StringHashMap(ModuleConstInfo) = std.StringHashMap(ModuleConstInfo).init(std.heap.page_allocator),
|
||||
module_const_map: std.StringHashMap(ModuleConstInfo),
|
||||
/// UFCS alias name → target function name.
|
||||
ufcs_alias_map: std.StringHashMap([]const u8) = std.StringHashMap([]const u8).init(std.heap.page_allocator),
|
||||
ufcs_alias_map: std.StringHashMap([]const u8),
|
||||
|
||||
// ── Source-keyed semantic caches (R5 §#4) ──
|
||||
// The source-partitioned analogues of `type_alias_map` / `module_const_map`
|
||||
@@ -682,6 +682,14 @@ pub const ProgramIndex = struct {
|
||||
.fn_ast_map = std.StringHashMap(*const ast.FnDecl).init(alloc),
|
||||
.qualified_fn_source = std.StringHashMap([]const u8).init(alloc),
|
||||
.global_names = std.StringHashMap(GlobalInfo).init(alloc),
|
||||
.foreign_class_map = std.StringHashMap(*const ast.ForeignClassDecl).init(alloc),
|
||||
.type_alias_map = std.StringHashMap(TypeId).init(alloc),
|
||||
.struct_template_map = std.StringHashMap(StructTemplate).init(alloc),
|
||||
.struct_template_by_decl = std.AutoHashMap(imports.DeclId, StructTemplate).init(alloc),
|
||||
.protocol_decl_map = std.StringHashMap(ProtocolDeclInfo).init(alloc),
|
||||
.protocol_ast_map = std.StringHashMap(*const ast.ProtocolDecl).init(alloc),
|
||||
.module_const_map = std.StringHashMap(ModuleConstInfo).init(alloc),
|
||||
.ufcs_alias_map = std.StringHashMap([]const u8).init(alloc),
|
||||
.type_aliases_by_source = std.StringHashMap(std.StringHashMap(TypeId)).init(alloc),
|
||||
.module_consts_by_source = std.StringHashMap(std.StringHashMap(ModuleConstInfo)).init(alloc),
|
||||
.globals_by_source = std.StringHashMap(std.StringHashMap(GlobalInfo)).init(alloc),
|
||||
|
||||
Reference in New Issue
Block a user