Files
cell/docs/spec/stone.md
2026-02-08 08:25:48 -06:00

83 lines
2.7 KiB
Markdown

---
title: "Stone Memory"
description: "Immutable arena allocation"
---
## Overview
Stone memory is a separate allocation arena for immutable values. Objects in stone memory are permanent — they are never moved, never freed, and never touched by the garbage collector.
The `stone()` function in ƿit petrifies a value, deeply freezing it and all its descendants. Stoned objects have the S bit set in their object header.
## The Stone Arena
Stone memory uses bump allocation from a contiguous arena:
```
stone_base ──────── stone_free ──────── stone_end
[allocated objects] [free space ]
```
Allocation advances `stone_free` forward. When the arena is exhausted, overflow pages are allocated via the system allocator and linked together:
```c
struct StonePage {
struct StonePage *next;
size_t size;
uint8_t data[];
};
```
## The S Bit
Bit 3 of the object header is the stone flag. When set:
- The object is **immutable** — writes disrupt
- The object is **excluded from GC** — the collector skips it entirely
- For text objects, the length field caches the **hash** instead of the character count (since the text cannot change, the hash is computed once and reused)
## What Gets Stoned
When `stone(value)` is called:
1. If the value is already stone, return immediately
2. Recursively walk all nested values (array elements, record fields, etc.)
3. Copy each mutable object into the stone arena
4. Set the S bit on each copied object
5. Return the stoned value
The operation is deep — an entire object graph becomes permanently immutable.
## Text Interning
The stone arena maintains a hash table for text interning. When a text value is stoned, it is looked up in the intern table. If an identical string already exists in stone memory, the existing one is reused. This deduplicates strings and makes equality comparison O(1) for stoned text.
The hash is computed with `fash64` over the packed UTF-32 words.
## Usage Patterns
### Module Return Values
Every module's return value is automatically stoned:
```javascript
// config.cm
return {
debug: true,
timeout: 30
}
// The returned object is stone — shared safely between actors
```
### Message Passing
Messages between actors are stoned before delivery, ensuring actors never share mutable state.
### Constants
Literal objects and arrays that can be determined at compile time may be allocated directly in stone memory.
## Relationship to GC
The Cheney copying collector only operates on the mutable heap. During collection, when the collector encounters a pointer to stone memory (S bit set), it skips it — stone objects are roots that never move. This means stone memory acts as a permanent root set with zero GC overhead.