1 import core.gc.registry;
2 import core.gc.gcinterface;
3 import core.stdc.stdlib;
4
5 static import core.memory;
6
7 extern (C) __gshared string[] rt_options = ["gcopt=gc:malloc"];
8
pragma(crt_constructor)9 extern (C) pragma(crt_constructor) void register_mygc()
10 {
11 registerGCFactory("malloc", &MallocGC.initialize);
12 }
13
register_default_gcs()14 extern (C) void register_default_gcs()
15 {
16 // remove default GCs
17 }
18
19 /** Simple GC that requires any pointers passed to it's API
20 to point to start of the allocation.
21 */
22 class MallocGC : GC
23 {
24 nothrow @nogc:
initialize()25 static GC initialize()
26 {
27 import core.stdc.string : memcpy;
28
29 __gshared ubyte[__traits(classInstanceSize, MallocGC)] buf;
30
31 auto init = typeid(MallocGC).initializer();
32 assert(init.length == buf.length);
33 auto instance = cast(MallocGC) memcpy(buf.ptr, init.ptr, init.length);
34 instance.__ctor();
35 return instance;
36 }
37
this()38 this()
39 {
40 }
41
Dtor()42 void Dtor()
43 {
44 }
45
enable()46 void enable()
47 {
48 }
49
disable()50 void disable()
51 {
52 }
53
collect()54 void collect() nothrow
55 {
56 }
57
collectNoStack()58 void collectNoStack() nothrow
59 {
60 }
61
minimize()62 void minimize() nothrow
63 {
64 }
65
getAttr(void * p)66 uint getAttr(void* p) nothrow
67 {
68 return 0;
69 }
70
setAttr(void * p,uint mask)71 uint setAttr(void* p, uint mask) nothrow
72 {
73 return mask;
74 }
75
clrAttr(void * p,uint mask)76 uint clrAttr(void* p, uint mask) nothrow
77 {
78 return mask;
79 }
80
malloc(size_t size,uint bits,const TypeInfo ti)81 void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow
82 {
83 return sentinelAdd(.malloc(size + sentinelSize), size);
84 }
85
qalloc(size_t size,uint bits,const scope TypeInfo ti)86 BlkInfo qalloc(size_t size, uint bits, const scope TypeInfo ti) nothrow
87 {
88 return BlkInfo(malloc(size, bits, ti), size);
89 }
90
calloc(size_t size,uint bits,const TypeInfo ti)91 void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow
92 {
93 return sentinelAdd(.calloc(1, size + sentinelSize), size);
94 }
95
realloc(void * p,size_t size,uint bits,const TypeInfo ti)96 void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow
97 {
98 return sentinelAdd(.realloc(p - sentinelSize, size + sentinelSize), size);
99 }
100
extend(void * p,size_t minsize,size_t maxsize,const TypeInfo ti)101 size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow
102 {
103 return 0;
104 }
105
reserve(size_t size)106 size_t reserve(size_t size) nothrow
107 {
108 return 0;
109 }
110
free(void * p)111 void free(void* p) nothrow
112 {
113 free(p - sentinelSize);
114 }
115
addrOf(void * p)116 void* addrOf(void* p) nothrow
117 {
118 return p;
119 }
120
sizeOf(void * p)121 size_t sizeOf(void* p) nothrow
122 {
123 return query(p).size;
124 }
125
query(void * p)126 BlkInfo query(void* p) nothrow
127 {
128 return p ? BlkInfo(p, sentinelGet(p)) : BlkInfo.init;
129 }
130
stats()131 core.memory.GC.Stats stats() nothrow
132 {
133 return core.memory.GC.Stats.init;
134 }
135
profileStats()136 core.memory.GC.ProfileStats profileStats() nothrow
137 {
138 return typeof(return).init;
139 }
140
addRoot(void * p)141 void addRoot(void* p) nothrow @nogc
142 {
143 }
144
removeRoot(void * p)145 void removeRoot(void* p) nothrow @nogc
146 {
147 }
148
rootIter()149 @property RootIterator rootIter() @nogc
150 {
151 return null;
152 }
153
addRange(void * p,size_t sz,const TypeInfo ti)154 void addRange(void* p, size_t sz, const TypeInfo ti) nothrow @nogc
155 {
156 }
157
removeRange(void * p)158 void removeRange(void* p) nothrow @nogc
159 {
160 }
161
rangeIter()162 @property RangeIterator rangeIter() @nogc
163 {
164 return null;
165 }
166
runFinalizers(const scope void[]segment)167 void runFinalizers(const scope void[] segment) nothrow
168 {
169 }
170
inFinalizer()171 bool inFinalizer() nothrow
172 {
173 return false;
174 }
175
allocatedInCurrentThread()176 ulong allocatedInCurrentThread() nothrow
177 {
178 return stats().allocatedInCurrentThread;
179 }
180
181 private:
182 // doesn't care for alignment
sentinelAdd(void * p,size_t value)183 static void* sentinelAdd(void* p, size_t value)
184 {
185 *cast(size_t*) p = value;
186 return p + sentinelSize;
187 }
188
sentinelGet(void * p)189 static size_t sentinelGet(void* p)
190 {
191 return *cast(size_t*)(p - sentinelSize);
192 }
193
194 enum sentinelSize = size_t.sizeof;
195 }
196
main()197 void main()
198 {
199 // test array append cache
200 char[] s;
201 foreach (char c; char.min .. char.max + 1)
202 s ~= c;
203 }
204