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.
- Layout
Id - Names a
Layoutincrate::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::Sharedobject keeps its lock in. - SHARED_
VALUE - The payload word a
Shape::Sharedobject’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.