Skip to content

Commit

Permalink
Merge pull request #12 from 9il/master
Browse files Browse the repository at this point in the history
Mir & BetterC rework, stage 1
  • Loading branch information
wilzbach authored Oct 24, 2018
2 parents 480b85b + f53b9fb commit fae6883
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 78 deletions.
42 changes: 36 additions & 6 deletions source/stdx/allocator/building_blocks/affix_allocator.d
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
alias parent = Allocator.instance;
}

private template Impl()
private template Impl(bool isStatic)
{

size_t goodAllocSize(size_t s)
Expand All @@ -97,6 +97,22 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
this.alignment);
}

static if (isStatic)
private size_t actualAllocationSize(size_t s)
{
assert(s > 0);
static if (!stateSize!Suffix)
{
return s + stateSize!Prefix;
}
else
{
return
roundUpToMultipleOf(s + stateSize!Prefix, Suffix.alignof)
+ stateSize!Suffix;
}
}
else
private size_t actualAllocationSize(size_t s) const
{
assert(s > 0);
Expand All @@ -112,6 +128,14 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
}
}

static if (isStatic)
private void[] actualAllocation(void[] b)
{
assert(b !is null);
return (b.ptr - stateSize!Prefix)
[0 .. actualAllocationSize(b.length)];
}
else
private void[] actualAllocation(void[] b) const
{
assert(b !is null);
Expand Down Expand Up @@ -343,15 +367,21 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
ref auto suffix(T)(T[] b);
}
else static if (is(typeof(Allocator.instance) == shared))
{
static shared AffixAllocator instance;
shared { mixin Impl!(); }
{ // for backward compatability
enum shared AffixAllocator instance = AffixAllocator();
static { mixin Impl!true; }
}
else
{
mixin Impl!();
static if (stateSize!Allocator == 0)
static __gshared AffixAllocator instance;
{
enum AffixAllocator instance = AffixAllocator();
static { mixin Impl!true; }
}
else
{
mixin Impl!false;
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions source/stdx/allocator/building_blocks/fallback_allocator.d
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct FallbackAllocator(Primary, Fallback)
*/
static if (!stateSize!Primary && !stateSize!Fallback)
{
static FallbackAllocator instance;
enum FallbackAllocator instance = FallbackAllocator();
}

/**
Expand Down Expand Up @@ -125,7 +125,7 @@ struct FallbackAllocator(Primary, Fallback)
static if (hasMember!(Primary, "owns"))
bool reallocate(ref void[] b, size_t newSize)
{
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);
if (b1.length != newSize) return false;
Expand Down Expand Up @@ -153,7 +153,7 @@ struct FallbackAllocator(Primary, Fallback)
|| hasMember!(Fallback, "alignedAllocate")))
bool alignedReallocate(ref void[] b, size_t newSize, uint a)
{
bool crossAllocatorMove(From, To)(ref From from, ref To to)
bool crossAllocatorMove(From, To)(auto ref From from, auto ref To to)
{
static if (!hasMember!(To, "alignedAllocate"))
{
Expand Down
26 changes: 13 additions & 13 deletions source/stdx/allocator/building_blocks/null_allocator.d
Original file line number Diff line number Diff line change
Expand Up @@ -20,48 +20,48 @@ struct NullAllocator
//size_t goodAllocSize(size_t n) shared const
//{ return .goodAllocSize(this, n); }
/// Always returns $(D null).
void[] allocate(size_t) shared { return null; }
static void[] allocate(size_t) { return null; }
/// Always returns $(D null).
void[] alignedAllocate(size_t, uint) shared { return null; }
static void[] alignedAllocate(size_t, uint) { return null; }
/// Always returns $(D null).
void[] allocateAll() shared { return null; }
static void[] allocateAll() { return null; }
/**
These methods return $(D false).
Precondition: $(D b is null). This is because there is no other possible
legitimate input.
*/
bool expand(ref void[] b, size_t s) shared
static bool expand(ref void[] b, size_t s)
{ assert(b is null); return s == 0; }
/// Ditto
bool reallocate(ref void[] b, size_t) shared
static bool reallocate(ref void[] b, size_t)
{ assert(b is null); return false; }
/// Ditto
bool alignedReallocate(ref void[] b, size_t, uint) shared
static bool alignedReallocate(ref void[] b, size_t, uint)
{ assert(b is null); return false; }
/// Returns $(D Ternary.no).
Ternary owns(void[]) shared const { return Ternary.no; }
static Ternary owns(void[]) { return Ternary.no; }
/**
Returns $(D Ternary.no).
*/
Ternary resolveInternalPointer(const void*, ref void[]) shared const
static Ternary resolveInternalPointer(const void*, ref void[])
{ return Ternary.no; }
/**
No-op.
Precondition: $(D b is null)
*/
bool deallocate(void[] b) shared { assert(b is null); return true; }
static bool deallocate(void[] b) { assert(b is null); return true; }
/**
No-op.
*/
bool deallocateAll() shared { return true; }
static bool deallocateAll() { return true; }
/**
Returns $(D Ternary.yes).
*/
Ternary empty() shared const { return Ternary.yes; }
static Ternary empty() { return Ternary.yes; }
/**
Returns the $(D shared) global instance of the $(D NullAllocator).
Returns the $(D static) global instance of the $(D NullAllocator).
*/
static shared NullAllocator instance;
enum NullAllocator instance = NullAllocator();
}

@system unittest
Expand Down
2 changes: 1 addition & 1 deletion source/stdx/allocator/building_blocks/quantizer.d
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct Quantizer(ParentAllocator, alias roundingFunction)
else
{
alias parent = ParentAllocator.instance;
static __gshared Quantizer instance;
enum Quantizer instance = Quantizer();
}

/**
Expand Down
16 changes: 8 additions & 8 deletions source/stdx/allocator/building_blocks/region.d
Original file line number Diff line number Diff line change
Expand Up @@ -599,20 +599,20 @@ version(Posix) struct SbrkRegion(uint minAlign = platformAlignment)

static assert(minAlign.isGoodStaticAlignment);
static assert(size_t.sizeof == (void*).sizeof);
private shared void* _brkInitial, _brkCurrent;
private static shared void* _brkInitial, _brkCurrent;

/**
Instance shared by all callers.
*/
static shared SbrkRegion instance;
enum SbrkRegion instance = SbrkRegion();

/**
Standard allocator primitives.
*/
enum uint alignment = minAlign;

/// Ditto
void[] allocate(size_t bytes) shared
static void[] allocate(size_t bytes)
{
static if (minAlign > 1)
const rounded = bytes.roundUpToMultipleOf(alignment);
Expand Down Expand Up @@ -640,7 +640,7 @@ version(Posix) struct SbrkRegion(uint minAlign = platformAlignment)
}

/// Ditto
void[] alignedAllocate(size_t bytes, uint a) shared
static void[] alignedAllocate(size_t bytes, uint a)
{
pthread_mutex_lock(cast(pthread_mutex_t*) &sbrkMutex) == 0 || assert(0);
scope(exit) pthread_mutex_unlock(cast(pthread_mutex_t*) &sbrkMutex) == 0
Expand Down Expand Up @@ -676,7 +676,7 @@ version(Posix) struct SbrkRegion(uint minAlign = platformAlignment)
the right.
*/
bool expand(ref void[] b, size_t delta) shared
static bool expand(ref void[] b, size_t delta)
{
if (b is null) return delta == 0;
assert(_brkInitial && _brkCurrent); // otherwise where did b come from?
Expand All @@ -700,7 +700,7 @@ version(Posix) struct SbrkRegion(uint minAlign = platformAlignment)
}

/// Ditto
Ternary owns(void[] b) shared
static Ternary owns(void[] b)
{
// No need to lock here.
assert(!_brkCurrent || b.ptr + b.length <= _brkCurrent);
Expand All @@ -715,7 +715,7 @@ version(Posix) struct SbrkRegion(uint minAlign = platformAlignment)
must be the last block allocated.
*/
bool deallocate(void[] b) shared
static bool deallocate(void[] b)
{
static if (minAlign > 1)
const rounded = b.length.roundUpToMultipleOf(alignment);
Expand All @@ -737,7 +737,7 @@ version(Posix) struct SbrkRegion(uint minAlign = platformAlignment)
that support reducing the break address (i.e. accept calls to $(D sbrk)
with negative offsets). OSX does not accept such.
*/
bool deallocateAll() shared
static bool deallocateAll()
{
pthread_mutex_lock(cast(pthread_mutex_t*) &sbrkMutex) == 0 || assert(0);
scope(exit) pthread_mutex_unlock(cast(pthread_mutex_t*) &sbrkMutex) == 0
Expand Down
28 changes: 20 additions & 8 deletions source/stdx/allocator/building_blocks/segregator.d
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,15 @@ struct Segregator(size_t threshold, SmallAllocator, LargeAllocator)
return _large.reallocate(b, s);
}
// Cross-allocator transgression
return .reallocate(this, b, s);
static if (!hasMember!(typeof(this), "instance"))
return .reallocate(this, b, s);
else
return .reallocate(instance, b, s);
}

static if (hasMember!(SmallAllocator, "alignedReallocate")
|| hasMember!(LargeAllocator, "alignedReallocate"))
bool reallocate(ref void[] b, size_t s)
bool alignedReallocate(ref void[] b, size_t s)
{
static if (hasMember!(SmallAllocator, "alignedReallocate"))
if (b.length <= threshold && s <= threshold)
Expand All @@ -210,7 +213,10 @@ struct Segregator(size_t threshold, SmallAllocator, LargeAllocator)
return _large.alignedReallocate(b, s);
}
// Cross-allocator transgression
return .alignedReallocate(this, b, s);
static if (!hasMember!(typeof(this), "instance"))
return .alignedReallocate(this, b, s);
else
return .alignedReallocate(instance, b, s);
}

static if (hasMember!(SmallAllocator, "owns")
Expand Down Expand Up @@ -261,15 +267,21 @@ struct Segregator(size_t threshold, SmallAllocator, LargeAllocator)
&& is(typeof(LargeAllocator.instance) == shared);

static if (sharedMethods)
{
static shared Segregator instance;
shared { mixin Impl!(); }
{ // for backward compatability
enum shared Segregator instance = Segregator();
static { mixin Impl!(); }
}
else
{
static if (!stateSize!SmallAllocator && !stateSize!LargeAllocator)
static __gshared Segregator instance;
mixin Impl!();
{
enum shared Segregator instance = Segregator();
static { mixin Impl!(); }
}
else
{
mixin Impl!();
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions source/stdx/allocator/common.d
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ defined. This is deliberate so allocators may use it internally within their own
implementation of $(D reallocate).
*/
bool reallocate(Allocator)(ref Allocator a, ref void[] b, size_t s)
bool reallocate(Allocator)(auto ref Allocator a, ref void[] b, size_t s)
{
if (b.length == s) return true;
static if (hasMember!(Allocator, "expand"))
Expand Down Expand Up @@ -378,7 +378,7 @@ defined. This is deliberate so allocators may use it internally within their own
implementation of $(D reallocate).
*/
bool alignedReallocate(Allocator)(ref Allocator alloc,
bool alignedReallocate(Allocator)(auto ref Allocator alloc,
ref void[] b, size_t s, uint a)
{
static if (hasMember!(Allocator, "expand"))
Expand Down
23 changes: 11 additions & 12 deletions source/stdx/allocator/gc_allocator.d
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ struct GCAllocator
deallocate) and $(D reallocate) methods are $(D @system) because they may
move memory around, leaving dangling pointers in user code.
*/
pure nothrow @trusted void[] allocate(size_t bytes) shared
static pure nothrow @trusted void[] allocate(size_t bytes)
{
if (!bytes) return null;
auto p = GC.malloc(bytes);
return p ? p[0 .. bytes] : null;
}

/// Ditto
@system bool expand(ref void[] b, size_t delta) shared
static @system bool expand(ref void[] b, size_t delta)
{
if (delta == 0) return true;
if (b is null) return false;
Expand All @@ -53,7 +53,7 @@ struct GCAllocator
}

/// Ditto
pure nothrow @system bool reallocate(ref void[] b, size_t newSize) shared
static pure nothrow @system bool reallocate(ref void[] b, size_t newSize)
{
import core.exception : OutOfMemoryError;
try
Expand All @@ -71,7 +71,7 @@ struct GCAllocator

/// Ditto
pure nothrow
Ternary resolveInternalPointer(const void* p, ref void[] result) shared
static Ternary resolveInternalPointer(const void* p, ref void[] result)
{
auto r = GC.addrOf(cast(void*) p);
if (!r) return Ternary.no;
Expand All @@ -80,14 +80,14 @@ struct GCAllocator
}

/// Ditto
pure nothrow @system bool deallocate(void[] b) shared
static pure nothrow @system bool deallocate(void[] b)
{
GC.free(b.ptr);
return true;
}

/// Ditto
size_t goodAllocSize(size_t n) shared
static size_t goodAllocSize(size_t n)
{
if (n == 0)
return 0;
Expand All @@ -105,15 +105,14 @@ struct GCAllocator
}

/**
Returns the global instance of this allocator type. The garbage collected
allocator is thread-safe, therefore all of its methods and `instance` itself
are $(D shared).
Returns the global instance of this allocator type. The garbage collected allocator is
thread-safe, therefore all of its methods are $(D static) and `instance` itself is
$(D shared).
*/

static shared GCAllocator instance;
enum GCAllocator instance = GCAllocator();

// Leave it undocummented for now.
nothrow @trusted void collect() shared
static nothrow @trusted void collect()
{
GC.collect();
}
Expand Down
Loading

0 comments on commit fae6883

Please sign in to comment.