This repository was archived by the owner on Jan 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy path010memory
More file actions
25 lines (21 loc) · 1.37 KB
/
010memory
File metadata and controls
25 lines (21 loc) · 1.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Wart's garbage collection was designed around one consideration:
minimize memory use at all times
To minimize memory use, Wart uses reference counting. Every cell tracks the
number of incoming pointers to it using a field called nrefs. Cycles must be
explicitly broken to be collected. Unused cells are immediately reclaimed.
Functions that change global state must always increment the nrefs of
*exactly* one cell across all paths. That makes it easy to reason about the
responsibilities of callers.
Always increment and decrement nrefs when saving a cell inside another: in the
car or cdr, or inside a table. Never assign to car or cdr or a table key by
hand. Use an existing primitive: set_car, set_cdr, set.
If you forget to decrement nrefs you have a memory leak. If you forget to
increment nrefs you have something worse: a prematurely garbage-collected cell
that may now be used for something else entirely. Old pointers to it can no
longer rely on what it contains; they may clobber or try to interpret
arbitrary data as the wrong type. All bets are off. Wart tries to loudly
detect this insidious class of error as immediately as possible. Every time a
cell is freed it resets its pointers to NULL; when it's reused its pointers
are initialized to nil. If Wart ever complains that it ran across NULL, it
means you forgot to decrement nrefs somewhere. All bets are off until it is
fixed.