AXIOM Документація Axiom
ENBLACKGRAYWHITE
Axiom · light

Детермінована пам’ять

two-pass відповідає на «скільки потрібно?», bundle — на «як спланувати багато таких операцій разом і reuse-нути storage?».

У веб-коді звично викликати функцію й дати allocator-у самому вирішити все інше. У embedded, аудіо, kernel або hard real-time це погана угода. Axiom робить memory requirements частиною API.

two-pass: спочатку план, потім робота

Conceptual target syntaxAxiom
1encode_json(user value) -> two_pass<bytes>:2    plan:3        RETURN json.encoded_size(value)4    build(view<u8> out):5        require out.size() >= planned_size6        json.encode_into(value, out)7        RETURN out[0..planned_size]
1

Функція повертає не heap-owned bytes, а two-pass operation.

2

Planning phase нічого великого не алокує.

3

Визначає точний потрібний size.

4

Build phase отримує storage від caller-а або bundle planner-а.

5

Capacity формалізована як contract.

6

Encoder пише в надану пам’ять.

7

Повертаємо view на фактично використаний діапазон.

Чому не просто malloc?

Тому що malloc відповідає на питання «чи пощастило зараз?». two-pass дозволяє до виконання дізнатися точну або доведену верхню межу. Caller може розмістити storage у static arena, stack region, shared buffer або memory pool без зміни алгоритму.

bundle: кілька операцій, один план

Memory schedulingAxiom
1bundle page_build:2    html = template.render(model)3    gzip = compress.gzip(html.output)4    frame = http.make_response(gzip.output)5END page_build67main:8    const usize peak = page_build.required_memory()9    byte storage[peak]10    const auto response = page_build.run(storage)
1

bundle описує групу пов’язаних операцій.

2

HTML renderer має власні plan/build lifetimes.

3

Compression починається після появи output першої операції.

4

HTTP framing — ще одна операція.

7

Compiler/planner обчислює peak, а не просто суму всіх scratch buffers.

8

Storage один.

9

Planner може reuse-нути ділянки, чиї lifetimes не перекриваються.

Найважливіша деталь

bundle не є arena allocator з красивим синтаксисом. Його цінність — у тому, що compiler бачить lifetime/interference graph. Якщо scratch для HTML уже помер до scratch compression, одна й та сама область може бути використана повторно. Для parallel branches lifetimes перекриваються, тому peak збільшується.

Upper bounds замість точних sizes

Не кожну операцію можна спланувати точно. API може повертати доведений upper bound. Це все одно сильніше за unbounded allocation, бо system manifest може сказати: процесу максимум потрібно, наприклад, 3.2 MiB RAM.