Monomorphization And Generic Code Control
Monomorphization turns generic declarations into concrete native symbols for
the layouts that a program actually uses. The goal is fast generated code
without uncontrolled binary-size or compile-time growth.
The authoritative files are:
monomorphization/schema.tsv;monomorphization/kinds.tsv;monomorphization/layouts.tsv;monomorphization/policy.tsv;monomorphization/verification-cases.tsv;release/monomorphization-map.tsv;perf/monomorphization-benchmarks.tsv;compat/monomorphization-contract.tsv.
Covered Generic Shapes
The current monomorphization contract covers:
- functions;
- methods;
- algebraic data types;
- effect rows;
- capability-polymorphic values;
- protocol/session values;
- static data;
- imported package symbols.
Concrete instances are keyed by their type, effect, capability, and protocol
arguments. Type parameters that do not affect code layout are erased from the
layout key so they can share generated code.
Deduplication And Polymorphization
Two instances share generated code when they have the same body hash, kind, and
layout key. The release map records the first concrete symbol and subsequent
dedup_of rows.
Polymorphization is required for type parameters that do not affect layout.
For example, a predicate whose body only checks an Option tag can share one
erased implementation for Option[I64] and Option[Text].
Dependency Partitions
Specializations are assigned to stable or volatile partitions:
- stable partitions contain generic code whose source and layout keys change
rarely;
- volatile partitions contain app or package instances that should compile
independently when package locks or app code change.
This keeps stable non-generic code separate from volatile specialized instances
for incremental code generation.
Release Map
The release map is release/monomorphization-map.tsv. It records:
- module;
- generic symbol;
- concrete instance key;
- concrete native symbol;
- kind;
- partition;
- layout key;
- body hash;
- estimated generated code size;
- dedup origin;
- source package;
- specialization policy.
The map is deterministic. make monomorphization-check regenerates it from the
valid fixture and compares it with the release artifact.
Budgets And Diagnostics
Run:
make monomorphization-check
The gate is bounded. It validates specialization collection, deduplication,
polymorphization, cross-package policy, release map determinism, and benchmark
records. It does not run self-hosting, broad backend matrices, emulator
matrices, or release benchmarks.
Stable diagnostics include:
NATIVE_MONO_EXPLOSION: requested or unique specialization count exceeds the
configured budget;
NATIVE_MONO_RECURSIVE: the generic dependency graph contains a recursive
specialization cycle;
NATIVE_MONO_LAYOUT: a requested type layout is unsupported;NATIVE_MONO_CODE_SIZE: estimated generated code exceeds the configured
code-size budget;
NATIVE_MONO_COMPILE_UNITS: partition count exceeds the compile-unit budget;NATIVE_MONO_POLICY: a cross-package specialization violates visibility or
package policy.
Benchmark Records
perf/monomorphization-benchmarks.tsv records representative library, runtime,
and app workloads with speed ratio, generated code size, compile-time cost,
requested instances, and unique instances. These rows are the bounded
monomorphization evidence for Milestone 3. Full release benchmark matrices are
owned by the final production benchmark milestone.