2 * Memory Cell header manipulation.
4 * This module has the Cell header definition and other support stuff (like
5 * BlkAttr) for the Naive Garbage Collector implementation. The Cell header has
6 * all the information needed for the bookkeeping of the GC allocated memory,
7 * like the mark bit, if the cell contents should be finalized or if it has
8 * pointers that should be scanned, etc.
11 * Copyright: Public Domain
12 * License: Public Domain
13 * Authors: Leandro Lucarella <llucax@gmail.com>
18 import cstdlib = tango.stdc.stdlib;
23 * Iterates a range of memory interpreting it as an array of void*.
25 * This function is designed to be used as a opApply implementation.
27 int op_apply_ptr_range(void* from, void* to, int delegate(ref void*) dg)
30 auto start = cast(void**) from;
31 auto end = cast(void**) to;
32 // since we sweep the memory range in word-sized steps, we need to make
33 // sure we don't scan for pointers beyond the end of the memory range
34 for (auto current = start; current + 1 <= end; current++) {
35 result = dg(*current);
42 /// Memory block (cell) attributes.
45 /// All attributes disabled.
47 /// The cell is an object with a finalizer.
48 FINALIZE = 0b0000_0001,
49 /// The cell has no pointers.
50 NO_SCAN = 0b0000_0010,
51 /// The cell should not be moved (unimplemented).
52 NO_MOVE = 0b0000_0100,
53 /// All attributes enabled.
58 * Memory block (cell) header.
60 * All memory cells in the GC heap have this header.
65 /// Size of the object stored in this memory cell.
68 /// Real size of the memory cell.
75 BlkAttr attr = BlkAttr.NONE;
77 /// Next cell (this is used for free/live lists linking).
82 assert (this.size > 0);
83 assert (this.capacity >= this.size);
87 * Allocate a new cell.
89 * Allocate a new cell (asking for fresh memory to the OS). The cell is
90 * initialized with the provided size and attributes. The capacity can be
91 * larger than the requested size, though. The attribute marked is set to
92 * true (assuming the cell will be used as soon as allocated) and next is
95 * Returns a pointer to the new cell or null if it can't allocate new
98 static Cell* alloc(size_t size, uint attr = 0)
100 auto cell = cast(Cell*) cstdlib.malloc(size + Cell.sizeof);
103 cell.capacity = size;
105 cell.attr = cast(BlkAttr) attr;
111 /// Free a cell allocated by Cell.alloc().
112 static void free(Cell* cell)
118 * Get a cell pointer for the cell that stores the object pointed to by
121 * If ptr is null, null is returned.
123 static Cell* from_ptr(void* ptr)
127 return cast(Cell*) (cast(byte*) ptr - Cell.sizeof);
130 /// Get the base address of the object stored in the cell.
133 return cast(void*) (cast(byte*) this + Cell.sizeof);
136 /// Return true if the cell should be finalized, false otherwise.
139 return cast(bool) (this.attr & BlkAttr.FINALIZE);
142 /// Return true if the cell should may have pointers, false otherwise.
145 return !(this.attr & BlkAttr.NO_SCAN);
149 * Iterates over the objects pointers.
151 * Current implementation interprets the whole object as if it were
154 int opApply(int delegate(ref void*) dg)
156 return op_apply_ptr_range(this.ptr, this.ptr + this.size, dg);
166 unittest // op_apply_ptr_range()
173 int r = op_apply_ptr_range(v.ptr, v.ptr + 10,
175 assert (cast (size_t) ptr == i++);
183 auto size = N * size_t.sizeof;
184 auto cell = Cell.alloc(size, BlkAttr.FINALIZE | BlkAttr.NO_SCAN);
185 assert (cell !is null);
186 assert (cell.ptr is cell + 1);
187 for (int i = 0; i < N; ++i) {
188 auto ptr = cast(size_t*) cell.ptr + i;
192 foreach (void* ptr; *cell) {
193 assert (cast(size_t) ptr == i++);
195 assert (*(cast(size_t*) cell.ptr) == N);
196 assert (cell.has_finalizer());
197 assert (!cell.has_pointers());
198 assert (cell is Cell.from_ptr(cell.ptr));
201 } // debug (UnitTest)
203 // vim: set et sw=4 sts=4 :