Skip to main content

Module layout

Module layout 

Source
Expand description

What a value is made of.

A Layout answers three questions about one family of values: how many words a value of it occupies, what each of those words holds, and where its parts are. That is all a frame slot, a heap object payload and a garbage collection need, and it is deliberately one vocabulary for all three — the stack region and the heap region are regions of one linear memory, and a struct inside a closure environment is laid out the way a struct in a frame is.

§A value is a run of words

docs/LINEAR_VM.md states the rule:

One slot is one eight-byte word. One value may occupy one or more consecutive slots.

So a Point { x: Int, y: Int } is two words where the value is, not one word naming two words somewhere else. That is what makes ADR 0001’s field-wise shallow copy a copy: two words in, two words out. The earlier design put every struct behind one address, which made an ordinary copy an alias and then needed a sharing bit and copy-on-write to conceal it — machinery that existed only to undo the representation choice.

§What is inline and what is an address

A value has a static width or it lives in the heap. Scalars, structs and enums have one; strings, collections, closures and erased values do not, and a value of one of those families is a single Repr::Ref word.

There is no fourth case. A declaration whose layout would contain itself has no static width either, and ADR 0035 decides that it is a checker error rather than something quietly given a heap representation — so a recursive cycle passes through one of the families above and is finite because that family is one word.

A heap object’s payload is described by a layout in exactly the same way, so a struct stored in an array element or a closure environment is inline in that payload, and the collector walks it with the same map.

§This table describes families, not instantiations

Array<String> and Array<Point> are one layout, because a reference is a reference. Array<Int> and Array<Duration> are two, because their words differ and a boundary has to know which. Nothing here grows a case because a program was refused, and nothing here is a runtime type universe: what an individual object is is a question its own header answers.

Structs§

Case
One case of an enum.
Field
One field of a struct, and where it starts.
Layout
The description of one family of values.
LayoutId
Names a Layout in crate::Program::layouts.
Part
One part of an enum case’s payload, and where it sits in the payload region.

Enums§

Shape
How a family’s words are arranged.

Constants§

SHARED_STATE
The payload word a Shape::Shared object keeps its lock in.
SHARED_VALUE
The payload word a Shape::Shared object’s wrapped value begins at.

Functions§

enum_layout
Lays out an enum’s payload region, answering the cases and the region’s words.
struct_layout
Lays out a struct’s fields, answering the fields and the flattened words.