module gc.cell;
+import cstdlib = tango.stdc.stdlib;
+
package:
/**
assert (this.capacity >= this.size);
}
+ /**
+ * Allocate a new cell.
+ *
+ * Allocate a new cell (asking for fresh memory to the OS). The cell is
+ * initialized with the provided size and attributes. The capacity can be
+ * larger than the requested size, though. The attribute marked is set to
+ * true (assuming the cell will be used as soon as allocated) and next is
+ * set to null.
+ *
+ * Returns a pointer to the new cell or null if it can't allocate new
+ * memory.
+ */
+ static Cell* alloc(size_t size, uint attr = 0)
+ {
+ auto cell = cast(Cell*) cstdlib.malloc(size + Cell.sizeof);
+ if (cell is null)
+ return null;
+ cell.capacity = size;
+ cell.size = size;
+ cell.attr = cast(BlkAttr) attr;
+ cell.marked = true;
+ cell.next = null;
+ return cell;
+ }
+
+ /// Free a cell allocated by Cell.alloc().
+ static void free(Cell* cell)
+ {
+ cstdlib.free(cell);
+ }
+
/**
* Get a cell pointer for the cell that stores the object pointed to by
* ptr.
private:
- import tango.stdc.stdlib: malloc;
-
unittest // op_apply_ptr_range()
{
size_t[10] v;
{
auto N = 10;
auto size = N * size_t.sizeof;
- auto cell = cast(Cell*) malloc(size + Cell.sizeof);
+ auto cell = Cell.alloc(size, BlkAttr.FINALIZE | BlkAttr.NO_SCAN);
assert (cell);
assert (cell.ptr is cell + 1);
- cell.size = size;
- cell.capacity = size;
- cell.attr = BlkAttr.FINALIZE | BlkAttr.NO_SCAN;
- cell.marked = true;
for (int i = 0; i < N; ++i) {
auto ptr = cast(size_t*) cell.ptr + i;
*ptr = i + N;
import gc.arch: push_registers, pop_registers;
// Standard imports
-import cstdlib = tango.stdc.stdlib;
import cstring = tango.stdc.string;
// Debug imports
{
foreach (cell; this.free_list) {
this.free_list.unlink(cell);
- cstdlib.free(cell);
+ Cell.free(cell);
}
}
// Find a free cell in the free list with enough space
auto cell = this.free_list.pop(size);
if (cell)
- goto success;
+ goto reuse;
// No room in the free list found, if the GC is enabled, trigger
// a collection and try again
this.collect();
cell = this.free_list.pop(size);
if (cell)
- goto success;
+ goto reuse;
}
- // No luck still, allocate new memory
- cell = cast(Cell*) cstdlib.malloc(size + Cell.sizeof);
- cell.capacity = 0; // so we can later tell it's new
+ // No luck still, allocate a new cell
+ cell = Cell.alloc(size, attr);
if (cell)
- goto success;
+ goto link;
// No memory
onOutOfMemoryError();
return null;
- success:
+ reuse:
cell.size = size;
- if (cell.capacity == 0) // fresh cell
- cell.capacity = size;
cell.attr = cast(BlkAttr) attr;
+
+ link:
this.live_list.link(cell);
return cell.ptr;
size_t reserve(size_t size)
{
assert (size > 0);
- auto cell = cast(Cell*) cstdlib.malloc(size + Cell.sizeof);
- if (!cell)
+ auto cell = Cell.alloc(size);
+ if (cell is null)
return 0;
- cell.size = size;
- cell.capacity = size;
this.free_list.link(cell);
- return size;
+ return cell.capacity;
}
/**