1 import core
.gc
.registry
;
2 import core
.gc
.gcinterface
;
3 import core
.stdc
.stdlib
;
5 static import core
.memory
;
7 extern (C
) __gshared string
[] rt_options
= ["gcopt=gc:malloc"];
9 extern (C
) pragma(crt_constructor
) void register_mygc()
11 registerGCFactory("malloc", &MallocGC
.initialize
);
14 extern (C
) void register_default_gcs()
19 /** Simple GC that requires any pointers passed to it's API
20 to point to start of the allocation.
25 static GC
initialize()
27 import core
.stdc
.string
: memcpy
;
29 __gshared
align(__traits(classInstanceAlignment
, MallocGC
))
30 ubyte[__traits(classInstanceSize
, MallocGC
)] buf
;
32 auto init
= typeid(MallocGC
).initializer();
33 assert(init
.length
== buf
.length
);
34 auto instance
= cast(MallocGC
) memcpy(buf
.ptr
, init
.ptr
, init
.length
);
55 void collect() nothrow
59 void collectNoStack() nothrow
63 void minimize() nothrow
67 uint getAttr(void* p
) nothrow
72 uint setAttr(void* p
, uint mask
) nothrow
77 uint clrAttr(void* p
, uint mask
) nothrow
82 void* malloc(size_t size
, uint bits
, const TypeInfo ti
) nothrow
84 return sentinelAdd(.malloc(size
+ sentinelSize
), size
);
87 BlkInfo
qalloc(size_t size
, uint bits
, const scope TypeInfo ti
) nothrow
89 return BlkInfo(malloc(size
, bits
, ti
), size
);
92 void* calloc(size_t size
, uint bits
, const TypeInfo ti
) nothrow
94 return sentinelAdd(.calloc(1, size
+ sentinelSize
), size
);
97 void* realloc(void* p
, size_t size
, uint bits
, const TypeInfo ti
) nothrow
99 return sentinelAdd(.realloc(p
- sentinelSize
, size
+ sentinelSize
), size
);
102 size_t
extend(void* p
, size_t minsize
, size_t maxsize
, const TypeInfo ti
) nothrow
107 size_t
reserve(size_t size
) nothrow
112 void free(void* p
) nothrow
114 free(p
- sentinelSize
);
117 void* addrOf(void* p
) nothrow
122 size_t
sizeOf(void* p
) nothrow
124 return query(p
).size
;
127 BlkInfo
query(void* p
) nothrow
129 return p ?
BlkInfo(p
, sentinelGet(p
)) : BlkInfo
.init
;
132 core
.memory
.GC
.Stats
stats() nothrow
134 return core
.memory
.GC
.Stats
.init
;
137 core
.memory
.GC
.ProfileStats
profileStats() nothrow
139 return typeof(return).init
;
142 void addRoot(void* p
) nothrow @nogc
146 void removeRoot(void* p
) nothrow @nogc
150 @property RootIterator
rootIter() @nogc
155 void addRange(void* p
, size_t sz
, const TypeInfo ti
) nothrow @nogc
159 void removeRange(void* p
) nothrow @nogc
163 @property RangeIterator
rangeIter() @nogc
168 void runFinalizers(const scope void[] segment
) nothrow
172 bool inFinalizer() nothrow
177 ulong allocatedInCurrentThread() nothrow
179 return stats().allocatedInCurrentThread
;
183 // doesn't care for alignment
184 static void* sentinelAdd(void* p
, size_t value
)
186 *cast(size_t
*) p
= value
;
187 return p
+ sentinelSize
;
190 static size_t
sentinelGet(void* p
)
192 return *cast(size_t
*)(p
- sentinelSize
);
195 enum sentinelSize
= size_t
.sizeof
;
200 // test array append cache
202 foreach (char c
; char.min
.. char.max
+ 1)