Skip to content

Commit

Permalink
dmd.root.rmem.Pool no longer necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
rainers committed Dec 26, 2020
1 parent c87e566 commit 77513e8
Showing 1 changed file with 0 additions and 95 deletions.
95 changes: 0 additions & 95 deletions vdc/dmdserver/dmdrmem.d
Original file line number Diff line number Diff line change
Expand Up @@ -111,98 +111,3 @@ extern (D) T[] arraydup(T)(const scope T[] s) nothrow
p[] = s;
return p;
}

import core.stdc.string;

// Define this to have Pool emit traces of objects allocated and disposed
//debug = Pool;
// Define this in addition to Pool to emit per-call traces (otherwise summaries are printed at the end).
//debug = PoolVerbose;

/**
Defines a pool for class objects. Objects can be fetched from the pool with make() and returned to the pool with
dispose(). Using a reference that has been dispose()d has undefined behavior. make() may return memory that has been
previously dispose()d.
Currently the pool has effect only if the GC is NOT used (i.e. either `version(GC)` or `mem.isGCEnabled` is false).
Otherwise `make` just forwards to `new` and `dispose` does nothing.
Internally the implementation uses a singly-linked freelist with a global root. The "next" pointer is stored in the
first word of each disposed object.
*/
struct Pool(T)
if (is(T == class))
{
/// The freelist's root
private static T root;

private static void trace(string fun, string f, uint l)()
{
debug(Pool)
{
debug(PoolVerbose)
{
fprintf(stderr, "%.*s(%u): bytes: %lu Pool!(%.*s)."~fun~"()\n",
cast(int) f.length, f.ptr, l, T.classinfo.initializer.length,
cast(int) T.stringof.length, T.stringof.ptr);
}
else
{
static ulong calls;
if (calls == 0)
{
// Plant summary printer
static extern(C) void summarize()
{
fprintf(stderr, "%.*s(%u): bytes: %lu calls: %lu Pool!(%.*s)."~fun~"()\n",
cast(int) f.length, f.ptr, l, ((T.classinfo.initializer.length + 15) & ~15) * calls,
calls, cast(int) T.stringof.length, T.stringof.ptr);
}
atexit(&summarize);
}
++calls;
}
}
}

/**
Returns a reference to a new object in the same state as if created with new T(args).
*/
static T make(string f = __FILE__, uint l = __LINE__, A...)(auto ref A args)
{
if (!root)
{
trace!("makeNew", f, l)();
return new T(args);
}
else
{
trace!("makeReuse", f, l)();
auto result = root;
root = *(cast(T*) root);
memcpy(cast(void*) result, T.classinfo.initializer.ptr, T.classinfo.initializer.length);
result.__ctor(args);
return result;
}
}

/**
Signals to the pool that this object is no longer used, so it can recycle its memory.
*/
static void dispose(string f = __FILE__, uint l = __LINE__, A...)(T goner)
{
version(GC)
{
if (mem.isGCEnabled) return;
}
trace!("dispose", f, l)();
debug
{
// Stomp the memory so as to maximize the chance of quick failure if used after dispose().
auto p = cast(ulong*) goner;
p[0 .. T.classinfo.initializer.length / ulong.sizeof] = 0xdeadbeef;
}
*(cast(T*) goner) = root;
root = goner;
}
}

0 comments on commit 77513e8

Please sign in to comment.