blob: ee2dcee92e4efc212ed127ba1a66e4330318a94d [file] [log] [blame]
import core.gc.registry;
import core.gc.gcinterface;
import core.stdc.stdlib;
static import core.memory;
extern (C) __gshared string[] rt_options = ["gcopt=gc:malloc"];
extern (C) pragma(crt_constructor) void register_mygc()
{
registerGCFactory("malloc", &MallocGC.initialize);
}
extern (C) void register_default_gcs()
{
// remove default GCs
}
/** Simple GC that requires any pointers passed to it's API
to point to start of the allocation.
*/
class MallocGC : GC
{
nothrow @nogc:
static GC initialize()
{
import core.stdc.string : memcpy;
__gshared align(__traits(classInstanceAlignment, MallocGC))
ubyte[__traits(classInstanceSize, MallocGC)] buf;
auto init = typeid(MallocGC).initializer();
assert(init.length == buf.length);
auto instance = cast(MallocGC) memcpy(buf.ptr, init.ptr, init.length);
instance.__ctor();
return instance;
}
this()
{
}
void Dtor()
{
}
void enable()
{
}
void disable()
{
}
void collect() nothrow
{
}
void collectNoStack() nothrow
{
}
void minimize() nothrow
{
}
uint getAttr(void* p) nothrow
{
return 0;
}
uint setAttr(void* p, uint mask) nothrow
{
return mask;
}
uint clrAttr(void* p, uint mask) nothrow
{
return mask;
}
void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow
{
return sentinelAdd(.malloc(size + sentinelSize), size);
}
BlkInfo qalloc(size_t size, uint bits, const scope TypeInfo ti) nothrow
{
return BlkInfo(malloc(size, bits, ti), size);
}
void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow
{
return sentinelAdd(.calloc(1, size + sentinelSize), size);
}
void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow
{
return sentinelAdd(.realloc(p - sentinelSize, size + sentinelSize), size);
}
size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow
{
return 0;
}
size_t reserve(size_t size) nothrow
{
return 0;
}
void free(void* p) nothrow
{
free(p - sentinelSize);
}
void* addrOf(void* p) nothrow
{
return p;
}
size_t sizeOf(void* p) nothrow
{
return query(p).size;
}
BlkInfo query(void* p) nothrow
{
return p ? BlkInfo(p, sentinelGet(p)) : BlkInfo.init;
}
core.memory.GC.Stats stats() nothrow
{
return core.memory.GC.Stats.init;
}
core.memory.GC.ProfileStats profileStats() nothrow
{
return typeof(return).init;
}
void addRoot(void* p) nothrow @nogc
{
}
void removeRoot(void* p) nothrow @nogc
{
}
@property RootIterator rootIter() @nogc
{
return null;
}
void addRange(void* p, size_t sz, const TypeInfo ti) nothrow @nogc
{
}
void removeRange(void* p) nothrow @nogc
{
}
@property RangeIterator rangeIter() @nogc
{
return null;
}
void runFinalizers(const scope void[] segment) nothrow
{
}
bool inFinalizer() nothrow
{
return false;
}
ulong allocatedInCurrentThread() nothrow
{
return stats().allocatedInCurrentThread;
}
private:
// doesn't care for alignment
static void* sentinelAdd(void* p, size_t value)
{
*cast(size_t*) p = value;
return p + sentinelSize;
}
static size_t sentinelGet(void* p)
{
return *cast(size_t*)(p - sentinelSize);
}
enum sentinelSize = size_t.sizeof;
}
void main()
{
// test array append cache
char[] s;
foreach (char c; char.min .. char.max + 1)
s ~= c;
}