aboutsummaryrefslogtreecommitdiff
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.d389
1 files changed, 190 insertions, 199 deletions
diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d
index 9ecb45b..5e05943 100644
--- a/source/tanya/memory/package.d
+++ b/source/tanya/memory/package.d
@@ -11,7 +11,7 @@
module tanya.memory;
import core.exception;
-public import std.experimental.allocator : make, makeArray;
+public import std.experimental.allocator : make;
import std.traits;
public import tanya.memory.allocator;
@@ -23,59 +23,61 @@ public import tanya.memory.allocator;
*/
mixin template DefaultAllocator()
{
- /// Allocator.
- protected shared Allocator allocator_;
+ /// Allocator.
+ protected shared Allocator allocator_;
- /**
- * Params:
- * allocator = The allocator should be used.
- */
- this(shared Allocator allocator)
- in
- {
- assert(allocator !is null);
- }
- body
- {
- this.allocator_ = allocator;
- }
+ /**
+ * Params:
+ * allocator = The allocator should be used.
+ *
+ * Precondition: $(D_INLINECODE allocator_ !is null)
+ */
+ this(shared Allocator allocator)
+ in
+ {
+ assert(allocator !is null);
+ }
+ body
+ {
+ this.allocator_ = allocator;
+ }
- /**
- * This property checks if the allocator was set in the constructor
- * and sets it to the default one, if not.
- *
- * Returns: Used allocator.
- *
- * Postcondition: $(D_INLINECODE allocator_ !is null)
- */
- protected @property shared(Allocator) allocator() nothrow @safe @nogc
- out (allocator)
- {
- assert(allocator !is null);
- }
- body
- {
- if (allocator_ is null)
- {
- allocator_ = defaultAllocator;
- }
- return allocator_;
- }
+ /**
+ * This property checks if the allocator was set in the constructor
+ * and sets it to the default one, if not.
+ *
+ * Returns: Used allocator.
+ *
+ * Postcondition: $(D_INLINECODE allocator !is null)
+ */
+ protected @property shared(Allocator) allocator() nothrow @safe @nogc
+ out (allocator)
+ {
+ assert(allocator !is null);
+ }
+ body
+ {
+ if (allocator_ is null)
+ {
+ allocator_ = defaultAllocator;
+ }
+ return allocator_;
+ }
- /// Ditto.
- @property shared(Allocator) allocator() const nothrow @trusted @nogc
- out (allocator)
- {
- assert(allocator !is null);
- }
- body
- {
- if (allocator_ is null)
- {
- return defaultAllocator;
- }
- return cast(shared Allocator) allocator_;
- }
+ /// Ditto.
+ @property shared(Allocator) allocator() const nothrow @trusted @nogc
+ out (allocator)
+ {
+ assert(allocator !is null);
+ }
+ body
+ {
+ if (allocator_ is null)
+ {
+ return defaultAllocator;
+ }
+ return cast(shared Allocator) allocator_;
+ }
}
// From druntime
@@ -85,28 +87,28 @@ shared Allocator allocator;
shared static this() nothrow @trusted @nogc
{
- import tanya.memory.mmappool;
- allocator = MmapPool.instance;
+ import tanya.memory.mallocator;
+ allocator = Mallocator.instance;
}
@property ref shared(Allocator) defaultAllocator() nothrow @safe @nogc
out (allocator)
{
- assert(allocator !is null);
+ assert(allocator !is null);
}
body
{
- return allocator;
+ return allocator;
}
@property void defaultAllocator(shared(Allocator) allocator) nothrow @safe @nogc
in
{
- assert(allocator !is null);
+ assert(allocator !is null);
}
body
{
- .allocator = allocator;
+ .allocator = allocator;
}
/**
@@ -114,101 +116,90 @@ body
* object of type $(D_PARAM T).
*
* Params:
- * T = Object type.
+ * T = Object type.
*/
template stateSize(T)
{
- static if (is(T == class) || is(T == interface))
- {
- enum stateSize = __traits(classInstanceSize, T);
- }
- else
- {
- enum stateSize = T.sizeof;
- }
+ static if (is(T == class) || is(T == interface))
+ {
+ enum stateSize = __traits(classInstanceSize, T);
+ }
+ else
+ {
+ enum stateSize = T.sizeof;
+ }
}
/**
* Params:
- * size = Raw size.
- * alignment = Alignment.
+ * size = Raw size.
+ * alignment = Alignment.
*
* Returns: Aligned size.
*/
-size_t alignedSize(in size_t size, in size_t alignment = 8) pure nothrow @safe @nogc
+size_t alignedSize(const size_t size, const size_t alignment = 8)
+pure nothrow @safe @nogc
{
- return (size - 1) / alignment * alignment + alignment;
+ return (size - 1) / alignment * alignment + alignment;
}
/**
* Internal function used to create, resize or destroy a dynamic array. It
- * throws $(D_PSYMBOL OutOfMemoryError) if $(D_PARAM Throws) is set. The new
- * allocated part of the array is initialized only if $(D_PARAM Init)
- * is set. This function can be trusted only in the data structures that
- * can ensure that the array is allocated/rellocated/deallocated with the
- * same allocator.
+ * may throw $(D_PSYMBOL OutOfMemoryError). The new
+ * allocated part of the array isn't initialized. This function can be trusted
+ * only in the data structures that can ensure that the array is
+ * allocated/rellocated/deallocated with the same allocator.
*
* Params:
- * T = Element type of the array being created.
- * Init = If should be initialized.
- * Throws = If $(D_PSYMBOL OutOfMemoryError) should be throwsn.
- * allocator = The allocator used for getting memory.
- * array = A reference to the array being changed.
- * length = New array length.
+ * T = Element type of the array being created.
+ * allocator = The allocator used for getting memory.
+ * array = A reference to the array being changed.
+ * length = New array length.
*
- * Returns: $(D_KEYWORD true) upon success, $(D_KEYWORD false) if memory could
- * not be reallocated. In the latter
+ * Returns: $(D_PARAM array).
*/
-package(tanya) bool resize(T,
- bool Init = true,
- bool Throws = true)
- (shared Allocator allocator,
- ref T[] array,
- in size_t length) @trusted
+package(tanya) T[] resize(T)(shared Allocator allocator,
+ auto ref T[] array,
+ const size_t length) @trusted
{
- void[] buf = array;
- static if (Init)
- {
- immutable oldLength = array.length;
- }
- if (!allocator.reallocate(buf, length * T.sizeof))
- {
- static if (Throws)
- {
- onOutOfMemoryError;
- }
- return false;
- }
- // Casting from void[] is unsafe, but we know we cast to the original type.
- array = cast(T[]) buf;
+ if (length == 0)
+ {
+ if (allocator.deallocate(array))
+ {
+ return null;
+ }
+ else
+ {
+ onOutOfMemoryErrorNoGC();
+ }
+ }
- static if (Init)
- {
- if (oldLength < length)
- {
- array[oldLength .. $] = T.init;
- }
- }
- return true;
+ void[] buf = array;
+ if (!allocator.reallocate(buf, length * T.sizeof))
+ {
+ onOutOfMemoryErrorNoGC();
+ }
+ // Casting from void[] is unsafe, but we know we cast to the original type.
+ array = cast(T[]) buf;
+
+ return array;
}
-package(tanya) alias resizeArray = resize;
-///
-unittest
+private unittest
{
- int[] p;
+ int[] p;
- defaultAllocator.resizeArray(p, 20);
- assert(p.length == 20);
+ p = defaultAllocator.resize(p, 20);
+ assert(p.length == 20);
- defaultAllocator.resizeArray(p, 30);
- assert(p.length == 30);
+ p = defaultAllocator.resize(p, 30);
+ assert(p.length == 30);
- defaultAllocator.resizeArray(p, 10);
- assert(p.length == 10);
+ p = defaultAllocator.resize(p, 10);
+ assert(p.length == 10);
- defaultAllocator.resizeArray(p, 0);
- assert(p is null);
+ p = defaultAllocator.resize(p, 0);
+ assert(p is null);
}
/**
@@ -217,101 +208,101 @@ unittest
* allocator.
*
* Params:
- * T = Type of $(D_PARAM p).
- * allocator = Allocator the $(D_PARAM p) was allocated with.
- * p = Object or array to be destroyed.
+ * T = Type of $(D_PARAM p).
+ * allocator = Allocator the $(D_PARAM p) was allocated with.
+ * p = Object or array to be destroyed.
*/
void dispose(T)(shared Allocator allocator, auto ref T* p)
{
- static if (hasElaborateDestructor!T)
- {
- destroy(*p);
- }
- () @trusted { allocator.deallocate((cast(void*) p)[0 .. T.sizeof]); }();
- p = null;
+ static if (hasElaborateDestructor!T)
+ {
+ destroy(*p);
+ }
+ () @trusted { allocator.deallocate((cast(void*) p)[0 .. T.sizeof]); }();
+ p = null;
}
/// Ditto.
void dispose(T)(shared Allocator allocator, auto ref T p)
- if (is(T == class) || is(T == interface))
+ if (is(T == class) || is(T == interface))
{
- if (p is null)
- {
- return;
- }
- static if (is(T == interface))
- {
- version(Windows)
- {
- import core.sys.windows.unknwn : IUnknown;
- static assert(!is(T: IUnknown), "COM interfaces can't be destroyed in "
- ~ __PRETTY_FUNCTION__);
- }
- auto ob = cast(Object) p;
- }
- else
- {
- alias ob = p;
- }
- auto ptr = cast(void *) ob;
+ if (p is null)
+ {
+ return;
+ }
+ static if (is(T == interface))
+ {
+ version(Windows)
+ {
+ import core.sys.windows.unknwn : IUnknown;
+ static assert(!is(T: IUnknown), "COM interfaces can't be destroyed in "
+ ~ __PRETTY_FUNCTION__);
+ }
+ auto ob = cast(Object) p;
+ }
+ else
+ {
+ alias ob = p;
+ }
+ auto ptr = cast(void *) ob;
- auto support = ptr[0 .. typeid(ob).initializer.length];
- scope (success)
- {
- () @trusted { allocator.deallocate(support); }();
- p = null;
- }
+ auto support = ptr[0 .. typeid(ob).initializer.length];
+ scope (success)
+ {
+ () @trusted { allocator.deallocate(support); }();
+ p = null;
+ }
- auto ppv = cast(void**) ptr;
- if (!*ppv)
- {
- return;
- }
- auto pc = cast(ClassInfo*) *ppv;
- scope (exit)
- {
- *ppv = null;
- }
+ auto ppv = cast(void**) ptr;
+ if (!*ppv)
+ {
+ return;
+ }
+ auto pc = cast(ClassInfo*) *ppv;
+ scope (exit)
+ {
+ *ppv = 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)
- {
- (cast(void function (Object) nothrow @safe @nogc) c.destructor)(ob);
- }
- }
- while ((c = c.base) !is 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)
+ {
+ (cast(void function (Object) nothrow @safe @nogc) c.destructor)(ob);
+ }
+ }
+ while ((c = c.base) !is null);
- if (ppv[1]) // if monitor is not null
- {
- _d_monitordelete(cast(Object) ptr, true);
- }
+ if (ppv[1]) // if monitor is not null
+ {
+ _d_monitordelete(cast(Object) ptr, true);
+ }
}
/// Ditto.
void dispose(T)(shared Allocator allocator, auto ref T[] p)
{
- static if (hasElaborateDestructor!(typeof(p[0])))
- {
- import std.algorithm.iteration;
- p.each!(e => destroy(e));
- }
- () @trusted { allocator.deallocate(p); }();
- p = null;
+ static if (hasElaborateDestructor!(typeof(p[0])))
+ {
+ import std.algorithm.iteration;
+ p.each!(e => destroy(e));
+ }
+ () @trusted { allocator.deallocate(p); }();
+ p = null;
}
unittest
{
- struct S
- {
- ~this()
- {
- }
- }
- auto p = cast(S[]) defaultAllocator.allocate(S.sizeof);
+ struct S
+ {
+ ~this()
+ {
+ }
+ }
+ auto p = cast(S[]) defaultAllocator.allocate(S.sizeof);
- defaultAllocator.dispose(p);
+ defaultAllocator.dispose(p);
}