]> git.ipfire.org Git - thirdparty/gcc.git/blame - libphobos/libdruntime/core/internal/gc/impl/manual/gc.d
d: Import dmd b8384668f, druntime e6caaab9, phobos 5ab9ad256 (v2.098.0-beta.1)
[thirdparty/gcc.git] / libphobos / libdruntime / core / internal / gc / impl / manual / gc.d
CommitLineData
b4c522fa
IB
1/**
2 * This module contains a minimal garbage collector implementation according to
3 * published requirements. This library is mostly intended to serve as an
4 * example, but it is usable in applications which do not rely on a garbage
5 * collector to clean up memory (ie. when dynamic array resizing is not used,
6 * and all memory allocated with 'new' is freed deterministically with
7 * 'delete').
8 *
9 * Please note that block attribute data must be tracked, or at a minimum, the
10 * FINALIZE bit must be tracked for any allocated memory block because calling
11 * rt_finalize on a non-object block can result in an access violation. In the
12 * allocator below, this tracking is done via a leading uint bitmask. A real
13 * allocator may do better to store this data separately, similar to the basic
14 * GC.
15 *
16 * Copyright: Copyright Sean Kelly 2005 - 2016.
5fee5ec3 17 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
b4c522fa
IB
18 * Authors: Sean Kelly
19 */
5fee5ec3 20module core.internal.gc.impl.manual.gc;
b4c522fa 21
5fee5ec3 22import core.gc.gcinterface;
b4c522fa 23
5fee5ec3 24import core.internal.container.array;
b4c522fa
IB
25
26import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc;
27static import core.memory;
28
29extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */
30
5fee5ec3
IB
31// register GC in C constructor (_STI_)
32extern(C) pragma(crt_constructor) void _d_register_manual_gc()
b4c522fa 33{
5fee5ec3
IB
34 import core.gc.registry;
35 registerGCFactory("manual", &initialize);
36}
b4c522fa 37
5fee5ec3
IB
38private GC initialize()
39{
40 import core.lifetime : emplace;
b4c522fa 41
5fee5ec3
IB
42 auto gc = cast(ManualGC) cstdlib.malloc(__traits(classInstanceSize, ManualGC));
43 if (!gc)
44 onOutOfMemoryError();
b4c522fa 45
5fee5ec3
IB
46 return emplace(gc);
47}
b4c522fa 48
5fee5ec3
IB
49class ManualGC : GC
50{
51 Array!Root roots;
52 Array!Range ranges;
b4c522fa
IB
53
54 this()
55 {
56 }
57
5fee5ec3 58 ~this()
b4c522fa 59 {
5fee5ec3
IB
60 // TODO: cannot free as memory is overwritten and
61 // the monitor is still read in rt_finalize (called by destroy)
62 // cstdlib.free(cast(void*) this);
b4c522fa
IB
63 }
64
65 void enable()
66 {
67 }
68
69 void disable()
70 {
71 }
72
73 void collect() nothrow
74 {
75 }
76
77 void collectNoStack() nothrow
78 {
79 }
80
81 void minimize() nothrow
82 {
83 }
84
85 uint getAttr(void* p) nothrow
86 {
87 return 0;
88 }
89
90 uint setAttr(void* p, uint mask) nothrow
91 {
92 return 0;
93 }
94
95 uint clrAttr(void* p, uint mask) nothrow
96 {
97 return 0;
98 }
99
100 void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow
101 {
102 void* p = cstdlib.malloc(size);
103
104 if (size && p is null)
105 onOutOfMemoryError();
106 return p;
107 }
108
5fee5ec3 109 BlkInfo qalloc(size_t size, uint bits, const scope TypeInfo ti) nothrow
b4c522fa
IB
110 {
111 BlkInfo retval;
112 retval.base = malloc(size, bits, ti);
113 retval.size = size;
114 retval.attr = bits;
115 return retval;
116 }
117
118 void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow
119 {
120 void* p = cstdlib.calloc(1, size);
121
122 if (size && p is null)
123 onOutOfMemoryError();
124 return p;
125 }
126
127 void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow
128 {
129 p = cstdlib.realloc(p, size);
130
131 if (size && p is null)
132 onOutOfMemoryError();
133 return p;
134 }
135
136 size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow
137 {
138 return 0;
139 }
140
141 size_t reserve(size_t size) nothrow
142 {
143 return 0;
144 }
145
5fee5ec3 146 void free(void* p) nothrow @nogc
b4c522fa
IB
147 {
148 cstdlib.free(p);
149 }
150
151 /**
152 * Determine the base address of the block containing p. If p is not a gc
153 * allocated pointer, return null.
154 */
5fee5ec3 155 void* addrOf(void* p) nothrow @nogc
b4c522fa
IB
156 {
157 return null;
158 }
159
160 /**
161 * Determine the allocated size of pointer p. If p is an interior pointer
162 * or not a gc allocated pointer, return 0.
163 */
5fee5ec3 164 size_t sizeOf(void* p) nothrow @nogc
b4c522fa
IB
165 {
166 return 0;
167 }
168
169 /**
170 * Determine the base address of the block containing p. If p is not a gc
171 * allocated pointer, return null.
172 */
173 BlkInfo query(void* p) nothrow
174 {
175 return BlkInfo.init;
176 }
177
178 core.memory.GC.Stats stats() nothrow
179 {
180 return typeof(return).init;
181 }
182
5fee5ec3
IB
183 core.memory.GC.ProfileStats profileStats() nothrow
184 {
185 return typeof(return).init;
186 }
187
b4c522fa
IB
188 void addRoot(void* p) nothrow @nogc
189 {
190 roots.insertBack(Root(p));
191 }
192
193 void removeRoot(void* p) nothrow @nogc
194 {
195 foreach (ref r; roots)
196 {
197 if (r is p)
198 {
199 r = roots.back;
200 roots.popBack();
201 return;
202 }
203 }
204 assert(false);
205 }
206
207 @property RootIterator rootIter() return @nogc
208 {
209 return &rootsApply;
210 }
211
212 private int rootsApply(scope int delegate(ref Root) nothrow dg)
213 {
214 foreach (ref r; roots)
215 {
216 if (auto result = dg(r))
217 return result;
218 }
219 return 0;
220 }
221
222 void addRange(void* p, size_t sz, const TypeInfo ti = null) nothrow @nogc
223 {
224 ranges.insertBack(Range(p, p + sz, cast() ti));
225 }
226
227 void removeRange(void* p) nothrow @nogc
228 {
229 foreach (ref r; ranges)
230 {
231 if (r.pbot is p)
232 {
233 r = ranges.back;
234 ranges.popBack();
235 return;
236 }
237 }
238 assert(false);
239 }
240
241 @property RangeIterator rangeIter() return @nogc
242 {
243 return &rangesApply;
244 }
245
246 private int rangesApply(scope int delegate(ref Range) nothrow dg)
247 {
248 foreach (ref r; ranges)
249 {
250 if (auto result = dg(r))
251 return result;
252 }
253 return 0;
254 }
255
5fee5ec3 256 void runFinalizers(const scope void[] segment) nothrow
b4c522fa
IB
257 {
258 }
259
260 bool inFinalizer() nothrow
261 {
262 return false;
263 }
5fee5ec3
IB
264
265 ulong allocatedInCurrentThread() nothrow
266 {
267 return typeof(return).init;
268 }
b4c522fa 269}