Understanding Memory Management in Turbine
In previous posts, I introduced Turbine, a scripting language with Markdown-like syntax and some interesting features, like its enum system. Today, I’ll dive a bit deeper and walk through how memory is managed under the hood.
Turbine uses automatic memory management powered by garbage collection (GC). That means you don’t need to manually call free()
like in C — memory cleanup is handled behind the scenes.
Still, if you’re interested in virtual machine (VM) internals or building your own language runtime, this post will give you an overview of how memory works in Turbine.
Primitive vs Reference Types
Turbine distinguishes between two kinds of values when it comes to memory management:
-
Primitive types (
int
,float
,bool
, etc.) are not managed by the GC. - Reference types (arrays, strings, user-defined structs, etc.) are managed by the GC.
Reference values are allocated on the heap, and what gets stored in VM registers or local variables is a reference (i.e. pointer) to those heap objects.
The garbage collector follows these references to determine which objects are still reachable and should stay alive.
Register-Based VM
Turbine’s virtual machine is register-based. Unlike stack-based VMs that use push
and pop
operations, Turbine instructions directly operate on register indices.
At compile time, the number of registers needed for a function is calculated — including all temporaries. This enables the VM to allocate just enough register space per function call, reducing overhead and avoiding unnecessary overlap between register lifetimes.
Each register can hold either a primitive value or a reference.
The GC inspects the registers and traces any reference-type values they contain, ensuring that only live heap objects stay around.
Precise Garbage Collection
Turbine implements a precise, tracing garbage collector, based on the classic mark-and-sweep algorithm.
Key characteristics:
- The GC knows exactly which values are references and which are primitives.
- It starts from roots (like global variables and VM registers), marks reachable objects, and sweeps the rest.
- Fields within heap objects are recursively traced.
Since Turbine is statically typed, the compiler can simulate register types during code generation and record which registers hold references at each instruction. This allows the GC to consult a stack map-like table at runtime — no guessing needed.
Unlike conservative GCs (common in C-based runtimes), Turbine’s collector doesn’t need to keep ambiguous data "just in case it’s a pointer". Instead, it uses static type information to precisely identify which values to trace.
Example: GC in Action
> gc
# main(args vec{string}) int
// Create a temporary vec
for i, val in vec{11, 22, 42}
print(2 * val)
// The register holding the vec gets overwritten
for i in 0..10
print(2 * i)
print("before ===============================")
gc.print()
// Temporary vec is now unreachable and should be collected
gc.collect()
print("after ===============================")
gc.print()
return 0
In this example, a temporary vec
is used in the first loop, and then its register is reused in the second loop, making the original reference unreachable.
Calling gc.collect()
doesn’t immediately run the GC. Instead, it sets a flag in the VM, and garbage collection is triggered at the next safe point.
However, in most cases, it feels like GC runs instantly, so it behaves much like manual collection from the programmer’s perspective.
Summary
- Turbine runs on a register-based virtual machine.
- Reference types are managed by a precise mark-and-sweep GC.
- Static type information enables accurate tracing without ambiguity.
As a developer, you don’t need to manually manage memory.
Links
Turbine is still under active development. Syntax and features are evolving, and I'm documenting the process as I go.
👉 GitHub (source)
👉 Project Docs
Interested?
If you're:
curious about designing a new language from scratch
looking for a small, embeddable scripting language that plays well with C/C++
into clean, Markdown-inspired syntax
…I’d love your thoughts and feedback!
More dev logs, code examples, and internals coming soon.
Top comments (0)