Updated allocator
This commit is contained in:
parent
f999e0e76f
commit
eec45fe608
|
@ -559,7 +559,7 @@ struct GCAllocator
|
||||||
/**
|
/**
|
||||||
Standard allocator methods per the semantics defined above. The $(D deallocate) and $(D reallocate) methods are $(D @system) because they may move memory around, leaving dangling pointers in user code.
|
Standard allocator methods per the semantics defined above. The $(D deallocate) and $(D reallocate) methods are $(D @system) because they may move memory around, leaving dangling pointers in user code.
|
||||||
*/
|
*/
|
||||||
@trusted void[] allocate(size_t bytes) shared
|
@trusted void[] allocate(size_t bytes) shared nothrow pure @safe
|
||||||
{
|
{
|
||||||
auto p = GC.malloc(bytes);
|
auto p = GC.malloc(bytes);
|
||||||
return p ? p[0 .. bytes] : null;
|
return p ? p[0 .. bytes] : null;
|
||||||
|
@ -581,7 +581,7 @@ struct GCAllocator
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
@system bool reallocate(ref void[] b, size_t newSize) shared
|
@system bool reallocate(ref void[] b, size_t newSize) shared nothrow pure
|
||||||
{
|
{
|
||||||
import core.exception : OutOfMemoryError;
|
import core.exception : OutOfMemoryError;
|
||||||
try
|
try
|
||||||
|
@ -598,15 +598,20 @@ struct GCAllocator
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
@system void deallocate(void[] b) shared
|
@system void deallocate(void[] b) shared nothrow pure
|
||||||
{
|
{
|
||||||
GC.free(b.ptr);
|
GC.free(b.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static shared(GCAllocator) it() pure nothrow @property @trusted
|
||||||
|
{
|
||||||
|
return cast(typeof(return)) _it;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the global instance of this allocator type. The garbage collected allocator is thread-safe, therefore all of its methods and $(D it) itself are $(D shared).
|
Returns the global instance of this allocator type. The garbage collected allocator is thread-safe, therefore all of its methods and $(D it) itself are $(D shared).
|
||||||
*/
|
*/
|
||||||
static shared GCAllocator it;
|
private static shared const GCAllocator _it;
|
||||||
|
|
||||||
// Leave it undocummented for now.
|
// Leave it undocummented for now.
|
||||||
@trusted void collect() shared
|
@trusted void collect() shared
|
||||||
|
@ -854,7 +859,7 @@ unittest
|
||||||
/**
|
/**
|
||||||
Returns s rounded up to a multiple of base.
|
Returns s rounded up to a multiple of base.
|
||||||
*/
|
*/
|
||||||
private size_t roundUpToMultipleOf(size_t s, uint base)
|
private size_t roundUpToMultipleOf(size_t s, uint base) pure nothrow @safe
|
||||||
{
|
{
|
||||||
assert(base);
|
assert(base);
|
||||||
auto rem = s % base;
|
auto rem = s % base;
|
||||||
|
@ -943,7 +948,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
|
||||||
static assert(
|
static assert(
|
||||||
!stateSize!Prefix || Allocator.alignment >= Prefix.alignof,
|
!stateSize!Prefix || Allocator.alignment >= Prefix.alignof,
|
||||||
"AffixAllocator does not work with allocators offering a smaller"
|
"AffixAllocator does not work with allocators offering a smaller"
|
||||||
" alignment than the prefix alignment.");
|
~ " alignment than the prefix alignment.");
|
||||||
static assert(alignment % Suffix.alignof == 0,
|
static assert(alignment % Suffix.alignof == 0,
|
||||||
"This restriction could be relaxed in the future.");
|
"This restriction could be relaxed in the future.");
|
||||||
|
|
||||||
|
@ -960,7 +965,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
|
||||||
parent allocator.
|
parent allocator.
|
||||||
*/
|
*/
|
||||||
static if (stateSize!Allocator) Allocator parent;
|
static if (stateSize!Allocator) Allocator parent;
|
||||||
else alias Allocator.it parent;
|
else alias parent = Allocator.it;
|
||||||
|
|
||||||
template Impl()
|
template Impl()
|
||||||
{
|
{
|
||||||
|
@ -1118,7 +1123,7 @@ unittest
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
alias AffixAllocator!(Mallocator, size_t) A;
|
alias A = AffixAllocator!(Mallocator, size_t);
|
||||||
auto b = A.it.allocate(10);
|
auto b = A.it.allocate(10);
|
||||||
A.it.prefix(b) = 10;
|
A.it.prefix(b) = 10;
|
||||||
assert(A.it.prefix(b) == 10);
|
assert(A.it.prefix(b) == 10);
|
||||||
|
@ -1902,10 +1907,10 @@ struct FallbackAllocator(Primary, Fallback)
|
||||||
If both $(D Primary) and $(D Fallback) are stateless, $(D FallbackAllocator)
|
If both $(D Primary) and $(D Fallback) are stateless, $(D FallbackAllocator)
|
||||||
defines a static instance $(D it).
|
defines a static instance $(D it).
|
||||||
*/
|
*/
|
||||||
static if (!stateSize!Primary && !stateSize!Fallback)
|
/+static if (!stateSize!Primary && !stateSize!Fallback)
|
||||||
{
|
{
|
||||||
static FallbackAllocator it;
|
static FallbackAllocator it;
|
||||||
}
|
}+/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The alignment offered is the minimum of the two allocators' alignment.
|
The alignment offered is the minimum of the two allocators' alignment.
|
||||||
|
@ -1916,7 +1921,7 @@ struct FallbackAllocator(Primary, Fallback)
|
||||||
Allocates memory trying the primary allocator first. If it returns $(D
|
Allocates memory trying the primary allocator first. If it returns $(D
|
||||||
null), the fallback allocator is tried.
|
null), the fallback allocator is tried.
|
||||||
*/
|
*/
|
||||||
void[] allocate(size_t s)
|
void[] allocate(size_t s) pure nothrow @safe
|
||||||
{
|
{
|
||||||
auto result = primary.allocate(s);
|
auto result = primary.allocate(s);
|
||||||
return result ? result : fallback.allocate(s);
|
return result ? result : fallback.allocate(s);
|
||||||
|
@ -1959,9 +1964,9 @@ struct FallbackAllocator(Primary, Fallback)
|
||||||
allocation from $(D fallback) to $(D primary).
|
allocation from $(D fallback) to $(D primary).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
bool reallocate(ref void[] b, size_t newSize)
|
bool reallocate(ref void[] b, size_t newSize) pure nothrow @trusted
|
||||||
{
|
{
|
||||||
bool crossAllocatorMove(From, To)(ref From from, ref To to)
|
bool crossAllocatorMove(From, To)(auto ref From from, auto ref To to)
|
||||||
{
|
{
|
||||||
auto b1 = to.allocate(newSize);
|
auto b1 = to.allocate(newSize);
|
||||||
if (!b1) return false;
|
if (!b1) return false;
|
||||||
|
@ -2004,7 +2009,7 @@ struct FallbackAllocator(Primary, Fallback)
|
||||||
*/
|
*/
|
||||||
static if (hasMember!(Primary, "deallocate")
|
static if (hasMember!(Primary, "deallocate")
|
||||||
|| hasMember!(Fallback, "deallocate"))
|
|| hasMember!(Fallback, "deallocate"))
|
||||||
void deallocate(void[] b)
|
void deallocate(void[] b) pure nothrow @trusted
|
||||||
{
|
{
|
||||||
if (primary.owns(b))
|
if (primary.owns(b))
|
||||||
{
|
{
|
||||||
|
@ -2014,7 +2019,7 @@ struct FallbackAllocator(Primary, Fallback)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static if (hasMember!(Fallback, "deallocate"))
|
static if (hasMember!(Fallback, "deallocate"))
|
||||||
return fallback.deallocate(b);
|
fallback.deallocate(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2216,11 +2221,6 @@ struct Freelist(ParentAllocator,
|
||||||
Allocates memory either off of the free list or from the parent allocator.
|
Allocates memory either off of the free list or from the parent allocator.
|
||||||
*/
|
*/
|
||||||
void[] allocate(size_t bytes)
|
void[] allocate(size_t bytes)
|
||||||
in
|
|
||||||
{
|
|
||||||
assert (_root !is null);
|
|
||||||
}
|
|
||||||
body
|
|
||||||
{
|
{
|
||||||
assert(bytes < size_t.max / 2);
|
assert(bytes < size_t.max / 2);
|
||||||
if (!inRange(bytes)) return parent.allocate(bytes);
|
if (!inRange(bytes)) return parent.allocate(bytes);
|
||||||
|
@ -2941,7 +2941,7 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
|
||||||
accommodate the request. For efficiency reasons, if $(D bytes == 0) the
|
accommodate the request. For efficiency reasons, if $(D bytes == 0) the
|
||||||
function returns an empty non-null slice.
|
function returns an empty non-null slice.
|
||||||
*/
|
*/
|
||||||
void[] allocate(size_t bytes)
|
void[] allocate(size_t bytes) pure nothrow @trusted
|
||||||
{
|
{
|
||||||
// Oddity: we don't return null for null allocation. Instead, we return
|
// Oddity: we don't return null for null allocation. Instead, we return
|
||||||
// an empty slice with a non-null ptr.
|
// an empty slice with a non-null ptr.
|
||||||
|
@ -2984,7 +2984,7 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
|
||||||
allocation. For efficiency reasons, if $(D b is null) the function returns
|
allocation. For efficiency reasons, if $(D b is null) the function returns
|
||||||
$(D false).
|
$(D false).
|
||||||
*/
|
*/
|
||||||
bool owns(void[] b) const
|
bool owns(void[] b) const nothrow pure @trusted
|
||||||
{
|
{
|
||||||
// No nullptr
|
// No nullptr
|
||||||
return b.ptr >= _store.ptr
|
return b.ptr >= _store.ptr
|
||||||
|
@ -2994,7 +2994,7 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
|
||||||
/**
|
/**
|
||||||
Deallocates all memory allocated with this allocator.
|
Deallocates all memory allocated with this allocator.
|
||||||
*/
|
*/
|
||||||
void deallocateAll()
|
void deallocateAll() pure nothrow @safe
|
||||||
{
|
{
|
||||||
_crt = _store.ptr;
|
_crt = _store.ptr;
|
||||||
}
|
}
|
||||||
|
@ -3716,6 +3716,12 @@ struct CascadingAllocator(alias make)
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
void[] allocate(size_t s)
|
void[] allocate(size_t s)
|
||||||
|
out (res)
|
||||||
|
{
|
||||||
|
import std.string;
|
||||||
|
assert (res.length == s, "res.length = %d, s = %d".format(res.length, s));
|
||||||
|
}
|
||||||
|
body
|
||||||
{
|
{
|
||||||
auto result = allocateNoGrow(s);
|
auto result = allocateNoGrow(s);
|
||||||
if (result) return result;
|
if (result) return result;
|
||||||
|
|
Loading…
Reference in New Issue