Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make KRR allocate @safe #6416

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions std/experimental/allocator/building_blocks/kernighan_ritchie.d
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,21 @@ struct KRRegion(ParentAllocator = NullAllocator)

this(this) @disable;

pure nothrow @trusted @nogc
void[] payload() inout
{
return (cast(ubyte*) &this)[0 .. size];
}

pure nothrow @trusted @nogc
bool adjacent(in Node* right) const
{
assert(right);
auto p = payload;
return p.ptr < right && right < p.ptr + p.length + Node.sizeof;
}

pure nothrow @trusted @nogc
bool coalesce(void* memoryEnd = null)
{
// Coalesce the last node before the memory end with any possible gap
Expand All @@ -138,6 +141,7 @@ struct KRRegion(ParentAllocator = NullAllocator)
return true;
}

@safe
Tuple!(void[], Node*) allocateHere(size_t bytes)
{
assert(bytes >= Node.sizeof);
Expand All @@ -151,7 +155,7 @@ struct KRRegion(ParentAllocator = NullAllocator)
if (leftover >= Node.sizeof)
{
// There's room for another node
auto newNode = cast(Node*) ((cast(ubyte*) &this) + bytes);
auto newNode = (() @trusted => cast(Node*) ((cast(ubyte*) &this) + bytes))();
n8sh marked this conversation as resolved.
Show resolved Hide resolved
newNode.size = leftover;
newNode.next = next == &this ? newNode : next;
assert(next);
Expand Down Expand Up @@ -395,6 +399,7 @@ struct KRRegion(ParentAllocator = NullAllocator)

Returns: A word-aligned buffer of `n` bytes, or `null`.
*/
@safe
void[] allocate(size_t n)
{
if (!n || !root) return null;
Expand All @@ -412,7 +417,7 @@ struct KRRegion(ParentAllocator = NullAllocator)
immutable balance = root.size - actualBytes;
if (balance >= Node.sizeof)
{
auto newRoot = cast(Node*) (result + actualBytes);
auto newRoot = (() @trusted => cast(Node*) (result + actualBytes))();
n8sh marked this conversation as resolved.
Show resolved Hide resolved
newRoot.next = root.next;
newRoot.size = balance;
root = newRoot;
Expand All @@ -422,7 +427,7 @@ struct KRRegion(ParentAllocator = NullAllocator)
root = null;
switchToFreeList;
}
return result[0 .. n];
return (() @trusted => result[0 .. n])();
}

// Not enough memory, switch to freelist mode and fall through
Expand Down Expand Up @@ -755,7 +760,7 @@ it actually returns memory to the operating system when possible.
n => KRRegion!GCAllocator(max(n * 16, 1024 * 1024)))());
}

@system unittest
@safe unittest
{
import std.experimental.allocator.gc_allocator : GCAllocator;

Expand All @@ -764,7 +769,7 @@ it actually returns memory to the operating system when possible.
void[][] array;
foreach (i; 1 .. 4)
{
array ~= alloc.allocate(i);
array ~= (() nothrow @safe => alloc.allocate(i))();
n8sh marked this conversation as resolved.
Show resolved Hide resolved
assert(array[$ - 1].length == i);
}
() nothrow @nogc { alloc.deallocate(array[1]); }();
Expand All @@ -779,7 +784,7 @@ it actually returns memory to the operating system when possible.
import std.typecons : Ternary;
auto alloc = KRRegion!()(
cast(ubyte[])(GCAllocator.instance.allocate(1024 * 1024)));
const store = alloc.allocate(KRRegion!().sizeof);
const store = (() pure nothrow @safe @nogc => alloc.allocate(KRRegion!().sizeof))();
auto p = cast(KRRegion!()* ) store.ptr;
import core.stdc.string : memcpy;
import std.algorithm.mutation : move;
Expand All @@ -792,7 +797,7 @@ it actually returns memory to the operating system when possible.
foreach (i; 0 .. array.length)
{
auto length = 100 * i + 1;
array[i] = p.allocate(length);
array[i] = (() pure nothrow @safe @nogc => p.allocate(length))();
assert(array[i].length == length, text(array[i].length));
assert((() pure nothrow @safe @nogc => p.owns(array[i]))() == Ternary.yes);
}
Expand Down Expand Up @@ -821,7 +826,7 @@ it actually returns memory to the operating system when possible.
assert(p.length == 1024 * 1024);
}

@system unittest
@safe unittest
{
import std.experimental.allocator.building_blocks;
import std.random;
Expand All @@ -848,7 +853,7 @@ it actually returns memory to the operating system when possible.

foreach (size; sizes)
{
bufs ~= a.allocate(size);
bufs ~= (() pure nothrow @safe @nogc => a.allocate(size))();
n8sh marked this conversation as resolved.
Show resolved Hide resolved
}

foreach (b; bufs.randomCover)
Expand All @@ -863,7 +868,7 @@ it actually returns memory to the operating system when possible.
test(sizes32);
}

@system unittest
@safe unittest
{
import std.experimental.allocator.building_blocks;
import std.random;
Expand All @@ -890,11 +895,11 @@ it actually returns memory to the operating system when possible.

foreach (size; sizes)
{
bufs ~= a.allocate(size);
bufs ~= (() pure nothrow @safe @nogc => a.allocate(size))();
}

() nothrow @nogc { a.deallocate(bufs[1]); }();
bufs ~= a.allocate(sizes[1] - word);
bufs ~= (() pure nothrow @safe @nogc => a.allocate(sizes[1] - word))();
n8sh marked this conversation as resolved.
Show resolved Hide resolved

() nothrow @nogc { a.deallocate(bufs[0]); }();
foreach (i; 2 .. bufs.length)
Expand Down