Give functions dedicated scratch storage

70e07e31490e16183a9f7d13b775f2a88ad5bc556087a77e355942af5143aab1
Large generated functions could exhaust the space left in the AST arena.
Register allocation then trapped instead of completing compilation.

Keep parsed nodes in the AST arena and use a dedicated scratch arena for
function lowering and register allocation. The scratch storage is reclaimed
after each generated function, so its capacity no longer depends on AST size.

Assisted-by: Codex:gpt-5.6
Alexis Sellier committed ago 1 parent 5e9e4cfc
compiler/radiance.rad +7 -4
33 33
/// Maximum number of test functions we can discover.
34 34
constant MAX_TESTS: u32 = 1024;
35 35
/// Maximum number of assembly source paths we can load per package.
36 36
constant MAX_ASM_MODULES: u32 = 64;
37 37
38 -
/// Temporary arena size (32 MB) - retains all parsed AST until resolution.
39 -
/// Used for: AST during parsing, then codegen scratch space.
38 +
/// AST arena size (32 MB) - retains parsed nodes throughout compilation.
40 39
constant TEMP_ARENA_SIZE: u32 = 33554432;
40 +
/// Per-function lowering and register-allocation arena size (16 MB).
41 +
constant FN_ARENA_SIZE: u32 = 16777216;
41 42
/// Main arena size (64 MB) - lives throughout compilation.
42 43
/// Used for: resolver data, types, symbols, global IL data, and codegen output.
43 44
constant MAIN_ARENA_SIZE: u32 = 67108864;
44 45
45 -
/// Temporary storage arena - reusable between phases.
46 +
/// AST storage arena.
46 47
static TEMP_ARENA: [u8; TEMP_ARENA_SIZE] = undefined;
48 +
/// Scratch storage reclaimed after each generated function.
49 +
static FN_ARENA: [u8; FN_ARENA_SIZE] = undefined;
47 50
/// Main storage arena - persists throughout compilation.
48 51
static MAIN_ARENA: [u8; MAIN_ARENA_SIZE] = undefined;
49 52
50 53
/// Module source code.
51 54
static MODULE_SOURCES: [u8; MAX_SOURCES_SIZE] = undefined;
1111 1114
    }
1112 1115
    // Run resolution phase.
1113 1116
    let mut res = try runResolver(&mut ctx, arena.nextId) catch {
1114 1117
        return 1;
1115 1118
    };
1116 -
    let mut fnArena = alloc::new(alloc::remainingBuf(&mut arena.arena));
1119 +
    let mut fnArena = alloc::new(&mut FN_ARENA[..]);
1117 1120
1118 1121
    // Lower, dump, and/or generate output.
1119 1122
    try compile(&mut ctx, &mut res, &mut fnArena) catch {
1120 1123
        return 1;
1121 1124
    };