"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/dmd/root/rmem.d" between
dmd-2.094.1.tar.gz and dmd-2.094.2.tar.gz

About: DMD (Digital Mars D) is the D reference compiler. D is an object-oriented, imperative, multi-paradigm system programming language.

rmem.d  (dmd-2.094.1):rmem.d  (dmd-2.094.2)
skipping to change at line 413 skipping to change at line 413
pure nothrow unittest pure nothrow unittest
{ {
auto s1 = [0, 1, 2]; auto s1 = [0, 1, 2];
auto s2 = s1.arraydup; auto s2 = s1.arraydup;
s2[0] = 4; s2[0] = 4;
assert(s1 == [0, 1, 2]); assert(s1 == [0, 1, 2]);
assert(s2 == [4, 1, 2]); assert(s2 == [4, 1, 2]);
string sEmpty; string sEmpty;
assert(sEmpty.arraydup is null); assert(sEmpty.arraydup is null);
} }
// 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. ma
ke() 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(G
C)` 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.initiali
zer.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 it
s 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;
}
}
 End of changes. 1 change blocks. 
0 lines changed or deleted 0 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)