1169691Skanimport core.gc.registry;
2169691Skanimport core.gc.gcinterface;
3169691Skanimport core.stdc.stdlib;
4169691Skan
5169691Skanstatic import core.memory;
6169691Skan
7169691Skanextern (C) __gshared string[] rt_options = ["gcopt=gc:malloc"];
8169691Skan
9169691Skanextern (C) pragma(crt_constructor) void register_mygc()
10169691Skan{
11169691Skan    registerGCFactory("malloc", &MallocGC.initialize);
12169691Skan}
13169691Skan
14169691Skanextern (C) void register_default_gcs()
15169691Skan{
16169691Skan    // remove default GCs
17169691Skan}
18169691Skan
19169691Skan/** Simple GC that requires any pointers passed to it's API
20169691Skan    to point to start of the allocation.
21169691Skan */
22169691Skanclass MallocGC : GC
23169691Skan{
24169691Skannothrow @nogc:
25169691Skan    static GC initialize()
26169691Skan    {
27169691Skan        import core.stdc.string : memcpy;
28169691Skan
29169691Skan        __gshared ubyte[__traits(classInstanceSize, MallocGC)] buf;
30169691Skan
31169691Skan        auto init = typeid(MallocGC).initializer();
32169691Skan        assert(init.length == buf.length);
33169691Skan        auto instance = cast(MallocGC) memcpy(buf.ptr, init.ptr, init.length);
34169691Skan        instance.__ctor();
35169691Skan        return instance;
36169691Skan    }
37169691Skan
38169691Skan    this()
39169691Skan    {
40169691Skan    }
41169691Skan
42169691Skan    void Dtor()
43169691Skan    {
44169691Skan    }
45169691Skan
46169691Skan    void enable()
47169691Skan    {
48169691Skan    }
49169691Skan
50169691Skan    void disable()
51169691Skan    {
52169691Skan    }
53169691Skan
54169691Skan    void collect() nothrow
55169691Skan    {
56169691Skan    }
57169691Skan
58169691Skan    void collectNoStack() nothrow
59169691Skan    {
60169691Skan    }
61169691Skan
62169691Skan    void minimize() nothrow
63169691Skan    {
64169691Skan    }
65169691Skan
66169691Skan    uint getAttr(void* p) nothrow
67169691Skan    {
68169691Skan        return 0;
69169691Skan    }
70169691Skan
71169691Skan    uint setAttr(void* p, uint mask) nothrow
72169691Skan    {
73169691Skan        return mask;
74169691Skan    }
75169691Skan
76169691Skan    uint clrAttr(void* p, uint mask) nothrow
77169691Skan    {
78169691Skan        return mask;
79169691Skan    }
80169691Skan
81169691Skan    void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow
82169691Skan    {
83169691Skan        return sentinelAdd(.malloc(size + sentinelSize), size);
84169691Skan    }
85169691Skan
86169691Skan    BlkInfo qalloc(size_t size, uint bits, const scope TypeInfo ti) nothrow
87169691Skan    {
88169691Skan        return BlkInfo(malloc(size, bits, ti), size);
89169691Skan    }
90169691Skan
91169691Skan    void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow
92169691Skan    {
93169691Skan        return sentinelAdd(.calloc(1, size + sentinelSize), size);
94169691Skan    }
95169691Skan
96169691Skan    void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow
97169691Skan    {
98169691Skan        return sentinelAdd(.realloc(p - sentinelSize, size + sentinelSize), size);
99169691Skan    }
100169691Skan
101169691Skan    size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow
102169691Skan    {
103169691Skan        return 0;
104169691Skan    }
105169691Skan
106169691Skan    size_t reserve(size_t size) nothrow
107169691Skan    {
108169691Skan        return 0;
109169691Skan    }
110169691Skan
111169691Skan    void free(void* p) nothrow
112169691Skan    {
113169691Skan        free(p - sentinelSize);
114169691Skan    }
115169691Skan
116169691Skan    void* addrOf(void* p) nothrow
117169691Skan    {
118169691Skan        return p;
119169691Skan    }
120169691Skan
121169691Skan    size_t sizeOf(void* p) nothrow
122169691Skan    {
123169691Skan        return query(p).size;
124169691Skan    }
125169691Skan
126169691Skan    BlkInfo query(void* p) nothrow
127169691Skan    {
128169691Skan        return p ? BlkInfo(p, sentinelGet(p)) : BlkInfo.init;
129169691Skan    }
130169691Skan
131169691Skan    core.memory.GC.Stats stats() nothrow
132169691Skan    {
133169691Skan        return core.memory.GC.Stats.init;
134169691Skan    }
135169691Skan
136169691Skan    core.memory.GC.ProfileStats profileStats() nothrow
137169691Skan    {
138169691Skan        return typeof(return).init;
139169691Skan    }
140169691Skan
141169691Skan    void addRoot(void* p) nothrow @nogc
142169691Skan    {
143169691Skan    }
144169691Skan
145169691Skan    void removeRoot(void* p) nothrow @nogc
146169691Skan    {
147169691Skan    }
148169691Skan
149169691Skan    @property RootIterator rootIter() @nogc
150169691Skan    {
151169691Skan        return null;
152169691Skan    }
153169691Skan
154169691Skan    void addRange(void* p, size_t sz, const TypeInfo ti) nothrow @nogc
155169691Skan    {
156169691Skan    }
157169691Skan
158169691Skan    void removeRange(void* p) nothrow @nogc
159169691Skan    {
160169691Skan    }
161169691Skan
162169691Skan    @property RangeIterator rangeIter() @nogc
163169691Skan    {
164169691Skan        return null;
165169691Skan    }
166169691Skan
167169691Skan    void runFinalizers(const scope void[] segment) nothrow
168169691Skan    {
169169691Skan    }
170169691Skan
171169691Skan    bool inFinalizer() nothrow
172169691Skan    {
173169691Skan        return false;
174169691Skan    }
175169691Skan
176169691Skan    ulong allocatedInCurrentThread() nothrow
177169691Skan    {
178169691Skan        return stats().allocatedInCurrentThread;
179169691Skan    }
180169691Skan
181169691Skanprivate:
182169691Skan    // doesn't care for alignment
183169691Skan    static void* sentinelAdd(void* p, size_t value)
184169691Skan    {
185169691Skan        *cast(size_t*) p = value;
186169691Skan        return p + sentinelSize;
187169691Skan    }
188169691Skan
189169691Skan    static size_t sentinelGet(void* p)
190169691Skan    {
191169691Skan        return *cast(size_t*)(p - sentinelSize);
192169691Skan    }
193169691Skan
194169691Skan    enum sentinelSize = size_t.sizeof;
195169691Skan}
196169691Skan
197169691Skanvoid main()
198169691Skan{
199169691Skan    // test array append cache
200169691Skan    char[] s;
201169691Skan    foreach (char c; char.min .. char.max + 1)
202169691Skan        s ~= c;
203169691Skan}
204169691Skan