]> git.llucax.com Git - software/dgc/naive.git/blob - cell.d
5c262056a1fddd5d0845b5506fb8726de03b819e
[software/dgc/naive.git] / cell.d
1 /**
2  * This module contains a minimal garbage collector implementation according to
3  * Tango requirements.  This library is mostly intended to serve as an example,
4  * but it is usable in applications which do not rely on a garbage collector
5  * to clean up memory (ie. when dynamic array resizing is not used, and all
6  * memory allocated with 'new' is freed deterministically with 'delete').
7  *
8  * Please note that block attribute data must be tracked, or at a minimum, the
9  * FINALIZE bit must be tracked for any allocated memory block because calling
10  * rt_finalize on a non-object block can result in an access violation.  In the
11  * allocator below, this tracking is done via a leading uint bitmask.  A real
12  * allocator may do better to store this data separately, similar to the basic
13  * GC normally used by Tango.
14  *
15  * Copyright: Public Domain
16  * License:   BOLA
17  * Authors:   Leandro Lucarella
18  */
19
20 module cell;
21
22 package:
23
24 enum BlkAttr : uint
25 {
26     FINALIZE = 0b0000_0001,
27     NO_SCAN  = 0b0000_0010,
28     NO_MOVE  = 0b0000_0100,
29     ALL_BITS = 0b1111_1111,
30 }
31
32 struct Cell
33 {
34
35     size_t size = 0;
36
37     size_t capacity = 0;
38
39     bool marked = true;
40
41     BlkAttr attr = cast(BlkAttr) 0;
42
43     Cell* next = null;
44
45     static Cell* from_ptr(void* ptr)
46     {
47         if (ptr is null)
48             return null;
49         return cast(Cell*) (cast(byte*) ptr - Cell.sizeof);
50     }
51
52     void* ptr()
53     {
54         return cast(void*) (cast(byte*) this + Cell.sizeof);
55     }
56
57     bool finalize()
58     {
59         return cast(bool) (this.attr & BlkAttr.FINALIZE);
60     }
61
62     bool has_pointers()
63     {
64         return !(this.attr & BlkAttr.NO_SCAN);
65     }
66
67     int opApply(int delegate(ref void*) dg)
68     {
69         int result = 0;
70         auto from = cast(void**) this.ptr;
71         auto to = cast(void**) this.ptr + this.size;
72         // TODO: alignment. The range should be aligned and the size
73         //       should be a multiple of the word size. If the later does
74         //       not hold, the last bytes that are not enough to build
75         //       a complete word should be ignored. Right now we are
76         //       doing invalid reads in that cases.
77         for (auto current = from; current < to; current++) {
78             result = dg(*current);
79             if (result)
80                 break;
81         }
82         return result;
83     }
84
85 }
86
87 // vim: set et sw=4 sts=4 :