summaryrefslogtreecommitdiff
path: root/source/tanya/memory/package.d
diff options
context:
space:
mode:
Diffstat (limited to 'source/tanya/memory/package.d')
-rw-r--r--source/tanya/memory/package.d71
1 files changed, 44 insertions, 27 deletions
diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d
index 9832d74..a19796e 100644
--- a/source/tanya/memory/package.d
+++ b/source/tanya/memory/package.d
@@ -10,14 +10,13 @@
*/
module tanya.memory;
-import core.exception;
-public import std.experimental.allocator : make, makeArray, expandArray,
- stateSize, shrinkArray;
+public import std.experimental.allocator : make, makeArray;
import std.traits;
public import tanya.memory.allocator;
public import tanya.memory.types;
-private extern (C) void _d_monitordelete(Object h, bool det) @nogc;
+// From druntime
+private extern (C) void _d_monitordelete(Object h, bool det) nothrow @nogc;
shared Allocator allocator;
@@ -38,6 +37,25 @@ shared static this() nothrow @safe @nogc
}
/**
+ * Returns the size in bytes of the state that needs to be allocated to hold an
+ * object of type $(D_PARAM T).
+ *
+ * Params:
+ * T = Object type.
+ */
+template stateSize(T)
+{
+ static if (is(T == class) || is(T == interface))
+ {
+ enum stateSize = __traits(classInstanceSize, T);
+ }
+ else
+ {
+ enum stateSize = T.sizeof;
+ }
+}
+
+/**
* Params:
* T = Element type of the array being created.
* allocator = The allocator used for getting memory.
@@ -89,7 +107,7 @@ unittest
}
private void deStruct(T)(ref T s)
- if (is(S == struct))
+ if (is(T == struct))
{
static if (__traits(hasMember, T, "__xdtor")
&& __traits(isSame, T, __traits(parent, s.__xdtor)))
@@ -150,43 +168,42 @@ void dispose(T)(shared Allocator allocator, T p)
alias ob = p;
}
auto ptr = cast(void *) ob;
+
auto support = ptr[0 .. typeid(ob).initializer.length];
+ scope (success)
+ {
+ allocator.deallocate(support);
+ }
auto ppv = cast(void**) ptr;
if (!*ppv)
{
return;
}
-
auto pc = cast(ClassInfo*) *ppv;
- try
+ scope (exit)
{
- auto c = *pc;
- do
- {
- if (c.destructor) // call destructor
- {
- (cast(void function (Object)) c.destructor)(cast(Object) ptr);
- }
- }
- while ((c = c.base) !is null);
+ *ppv = null;
+ }
- if (ppv[1]) // if monitor is not null
+ auto c = *pc;
+ do
+ {
+ // Assume the destructor is @nogc. Leave it nothrow since the destructor
+ // shouldn't throw and if it does, it is an error anyway.
+ if (c.destructor)
{
- _d_monitordelete(cast(Object) ptr, true);
+ (cast(void function (Object) nothrow @nogc) c.destructor)(ob);
}
- auto w = (*pc).initializer;
- ptr[0 .. w.length] = w[];
- }
- catch (Exception e)
- {
- onFinalizeError(*pc, e);
}
- finally
+ while ((c = c.base) !is null);
+
+ if (ppv[1]) // if monitor is not null
{
- *ppv = null;
+ _d_monitordelete(cast(Object) ptr, true);
}
- allocator.deallocate(support);
+ auto w = (*pc).initializer;
+ ptr[0 .. w.length] = w[];
}
/// Ditto.