xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/testsuite/libphobos.init_fini/custom_gc.d (revision b1e838363e3c6fc78a55519254d99869742dd33c)
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