Safe-ify internal code.

This commit is contained in:
Sönke Ludwig 2016-11-02 20:53:30 +01:00
parent 6094971947
commit 616130cef1
3 changed files with 38 additions and 35 deletions

View file

@ -50,7 +50,7 @@ struct AllocAppender(ArrayType : E[], E) {
} }
this(Allocator alloc, ElemType[] initial_buffer = null) this(Allocator alloc, ElemType[] initial_buffer = null)
{ @safe {
m_alloc = alloc; m_alloc = alloc;
m_data = initial_buffer; m_data = initial_buffer;
m_remaining = initial_buffer; m_remaining = initial_buffer;
@ -75,10 +75,10 @@ struct AllocAppender(ArrayType : E[], E) {
*/ */
void reserve(size_t amount) void reserve(size_t amount)
{ @safe {
size_t nelems = m_data.length - m_remaining.length; size_t nelems = m_data.length - m_remaining.length;
if (!m_data.length) { if (!m_data.length) {
m_data = cast(ElemType[])m_alloc.alloc(amount*E.sizeof); m_data = () @trusted { return cast(ElemType[])m_alloc.alloc(amount*E.sizeof); } ();
m_remaining = m_data; m_remaining = m_data;
m_allocatedBuffer = true; m_allocatedBuffer = true;
} }
@ -87,9 +87,9 @@ struct AllocAppender(ArrayType : E[], E) {
import std.digest.crc; import std.digest.crc;
auto checksum = crc32Of(m_data[0 .. nelems]); auto checksum = crc32Of(m_data[0 .. nelems]);
} }
if (m_allocatedBuffer) m_data = cast(ElemType[])m_alloc.realloc(m_data, (nelems+amount)*E.sizeof); if (m_allocatedBuffer) m_data = () @trusted { return cast(ElemType[])m_alloc.realloc(m_data, (nelems+amount)*E.sizeof); } ();
else { else {
auto newdata = cast(ElemType[])m_alloc.alloc((nelems+amount)*E.sizeof); auto newdata = () @trusted { return cast(ElemType[])m_alloc.alloc((nelems+amount)*E.sizeof); } ();
newdata[0 .. nelems] = m_data[0 .. nelems]; newdata[0 .. nelems] = m_data[0 .. nelems];
m_data = newdata; m_data = newdata;
m_allocatedBuffer = true; m_allocatedBuffer = true;
@ -100,28 +100,28 @@ struct AllocAppender(ArrayType : E[], E) {
} }
void put(E el) void put(E el)
{ @safe {
if( m_remaining.length == 0 ) grow(1); if( m_remaining.length == 0 ) grow(1);
m_remaining[0] = el; m_remaining[0] = el;
m_remaining = m_remaining[1 .. $]; m_remaining = m_remaining[1 .. $];
} }
void put(ArrayType arr) void put(ArrayType arr)
{ @safe {
if (m_remaining.length < arr.length) grow(arr.length); if (m_remaining.length < arr.length) grow(arr.length);
m_remaining[0 .. arr.length] = arr[]; m_remaining[0 .. arr.length] = arr[];
m_remaining = m_remaining[arr.length .. $]; m_remaining = m_remaining[arr.length .. $];
} }
static if( !hasAliasing!E ){ static if( !hasAliasing!E ){
void put(in ElemType[] arr){ void put(in ElemType[] arr) @trusted {
put(cast(ArrayType)arr); put(cast(ArrayType)arr);
} }
} }
static if( is(ElemType == char) ){ static if( is(ElemType == char) ){
void put(dchar el) void put(dchar el)
{ @trusted {
if( el < 128 ) put(cast(char)el); if( el < 128 ) put(cast(char)el);
else { else {
char[4] buf; char[4] buf;
@ -133,7 +133,7 @@ struct AllocAppender(ArrayType : E[], E) {
static if( is(ElemType == wchar) ){ static if( is(ElemType == wchar) ){
void put(dchar el) void put(dchar el)
{ @trusted {
if( el < 128 ) put(cast(wchar)el); if( el < 128 ) put(cast(wchar)el);
else { else {
wchar[3] buf; wchar[3] buf;
@ -161,7 +161,7 @@ struct AllocAppender(ArrayType : E[], E) {
} }
void grow(size_t min_free) void grow(size_t min_free)
{ @safe {
if( !m_data.length && min_free < 16 ) min_free = 16; if( !m_data.length && min_free < 16 ) min_free = 16;
auto min_size = m_data.length + min_free - m_remaining.length; auto min_size = m_data.length + min_free - m_remaining.length;

View file

@ -36,13 +36,15 @@ struct DefaultHashMapTraits(Key) {
return typeinfo.getHash(&k); return typeinfo.getHash(&k);
} }
static @nogc nothrow size_t properlyTypedWrapper(in ref Key k) { return 0; } static @nogc nothrow size_t properlyTypedWrapper(in ref Key k) { return 0; }
return (cast(typeof(&properlyTypedWrapper))&hashWrapper)(k); return () @trusted { return (cast(typeof(&properlyTypedWrapper))&hashWrapper)(k); } ();
} }
} }
} }
struct HashMap(TKey, TValue, Traits = DefaultHashMapTraits!TKey) struct HashMap(TKey, TValue, Traits = DefaultHashMapTraits!TKey)
{ {
@safe:
import vibe.internal.traits : isOpApplyDg; import vibe.internal.traits : isOpApplyDg;
alias Key = TKey; alias Key = TKey;
@ -52,7 +54,7 @@ struct HashMap(TKey, TValue, Traits = DefaultHashMapTraits!TKey)
UnConst!Key key = Traits.clearValue; UnConst!Key key = Traits.clearValue;
Value value; Value value;
this(Key key, Value value) { this.key = cast(UnConst!Key)key; this.value = value; } this(Key key, Value value) @trusted { this.key = cast(UnConst!Key)key; this.value = value; }
} }
private { private {
TableEntry[] m_table; // NOTE: capacity is always POT TableEntry[] m_table; // NOTE: capacity is always POT
@ -69,7 +71,7 @@ struct HashMap(TKey, TValue, Traits = DefaultHashMapTraits!TKey)
~this() ~this()
{ {
clear(); clear();
if (m_table.ptr !is null) freeArray(m_allocator, m_table); if (m_table.ptr !is null) () @trusted { freeArray(m_allocator, m_table); } ();
} }
@disable this(this); @disable this(this);
@ -293,8 +295,9 @@ nothrow unittest {
performNoGCOps(); performNoGCOps();
} }
unittest { // test for proper use of constructor/post-blit/destructor @safe unittest { // test for proper use of constructor/post-blit/destructor
static struct Test { static struct Test {
@safe:
static size_t constructedCounter = 0; static size_t constructedCounter = 0;
bool constructed = false; bool constructed = false;
this(int) { constructed = true; constructedCounter++; } this(int) { constructed = true; constructedCounter++; }

View file

@ -20,7 +20,7 @@ import std.exception : enforceEx;
import std.traits; import std.traits;
import std.algorithm; import std.algorithm;
Allocator defaultAllocator() nothrow Allocator defaultAllocator() @trusted nothrow
{ {
version(VibeManualMemoryManagement){ version(VibeManualMemoryManagement){
return manualAllocator(); return manualAllocator();
@ -36,7 +36,7 @@ Allocator defaultAllocator() nothrow
} }
} }
Allocator manualAllocator() nothrow Allocator manualAllocator() @trusted nothrow
{ {
static __gshared Allocator alloc; static __gshared Allocator alloc;
if( !alloc ){ if( !alloc ){
@ -48,7 +48,7 @@ Allocator manualAllocator() nothrow
return alloc; return alloc;
} }
Allocator threadLocalAllocator() nothrow Allocator threadLocalAllocator() @safe nothrow
{ {
static Allocator alloc; static Allocator alloc;
if (!alloc) { if (!alloc) {
@ -60,7 +60,7 @@ Allocator threadLocalAllocator() nothrow
return alloc; return alloc;
} }
Allocator threadLocalManualAllocator() nothrow Allocator threadLocalManualAllocator() @safe nothrow
{ {
static Allocator alloc; static Allocator alloc;
if (!alloc) { if (!alloc) {
@ -118,7 +118,7 @@ nothrow:
enum size_t alignment = 0x10; enum size_t alignment = 0x10;
enum size_t alignmentMask = alignment-1; enum size_t alignmentMask = alignment-1;
void[] alloc(size_t sz) void[] alloc(size_t sz) @safe
out { assert((cast(size_t)__result.ptr & alignmentMask) == 0, "alloc() returned misaligned data."); } out { assert((cast(size_t)__result.ptr & alignmentMask) == 0, "alloc() returned misaligned data."); }
void[] realloc(void[] mem, size_t new_sz) void[] realloc(void[] mem, size_t new_sz)
@ -143,7 +143,7 @@ class LockAllocator : Allocator {
private { private {
Allocator m_base; Allocator m_base;
} }
this(Allocator base) nothrow { m_base = base; } this(Allocator base) @safe nothrow { m_base = base; }
void[] alloc(size_t sz) { void[] alloc(size_t sz) {
static if (!synchronizedIsNothrow) static if (!synchronizedIsNothrow)
scope (failure) assert(0, "Internal error: function should be nothrow"); scope (failure) assert(0, "Internal error: function should be nothrow");
@ -185,7 +185,7 @@ final class DebugAllocator : Allocator {
size_t m_maxBytes; size_t m_maxBytes;
} }
this(Allocator base_allocator) nothrow this(Allocator base_allocator) @safe nothrow
{ {
m_baseAlloc = base_allocator; m_baseAlloc = base_allocator;
m_blocks = HashMap!(void*, size_t)(manualAllocator()); m_blocks = HashMap!(void*, size_t)(manualAllocator());
@ -199,8 +199,8 @@ final class DebugAllocator : Allocator {
{ {
auto ret = m_baseAlloc.alloc(sz); auto ret = m_baseAlloc.alloc(sz);
assert(ret.length == sz, "base.alloc() returned block with wrong size."); assert(ret.length == sz, "base.alloc() returned block with wrong size.");
assert(m_blocks.getNothrow(ret.ptr, size_t.max) == size_t.max, "base.alloc() returned block that is already allocated."); assert(m_blocks.getNothrow(&ret[0], size_t.max) == size_t.max, "base.alloc() returned block that is already allocated.");
m_blocks[ret.ptr] = sz; m_blocks[&ret[0]] = sz;
m_bytes += sz; m_bytes += sz;
if( m_bytes > m_maxBytes ){ if( m_bytes > m_maxBytes ){
m_maxBytes = m_bytes; m_maxBytes = m_bytes;
@ -236,7 +236,7 @@ final class DebugAllocator : Allocator {
final class MallocAllocator : Allocator { final class MallocAllocator : Allocator {
void[] alloc(size_t sz) void[] alloc(size_t sz)
{ @trusted {
static err = new immutable OutOfMemoryError; static err = new immutable OutOfMemoryError;
auto ptr = .malloc(sz + Allocator.alignment); auto ptr = .malloc(sz + Allocator.alignment);
if (ptr is null) throw err; if (ptr is null) throw err;
@ -277,7 +277,7 @@ final class MallocAllocator : Allocator {
final class GCAllocator : Allocator { final class GCAllocator : Allocator {
void[] alloc(size_t sz) void[] alloc(size_t sz)
{ @trusted {
auto mem = GC.malloc(sz+Allocator.alignment); auto mem = GC.malloc(sz+Allocator.alignment);
auto alignedmem = adjustPointerAlignment(mem); auto alignedmem = adjustPointerAlignment(mem);
assert(alignedmem - mem <= Allocator.alignment); assert(alignedmem - mem <= Allocator.alignment);
@ -322,7 +322,7 @@ final class AutoFreeListAllocator : Allocator {
Allocator m_baseAlloc; Allocator m_baseAlloc;
} }
this(Allocator base_allocator) nothrow this(Allocator base_allocator) @safe nothrow
{ {
m_baseAlloc = base_allocator; m_baseAlloc = base_allocator;
foreach (i; iotaTuple!freeListCount) foreach (i; iotaTuple!freeListCount)
@ -416,7 +416,7 @@ final class PoolAllocator : Allocator {
size_t m_poolSize; size_t m_poolSize;
} }
this(size_t pool_size, Allocator base) nothrow this(size_t pool_size, Allocator base) @safe nothrow
{ {
m_poolSize = pool_size; m_poolSize = pool_size;
m_baseAllocator = base; m_baseAllocator = base;
@ -456,7 +456,7 @@ final class PoolAllocator : Allocator {
if( !p ){ if( !p ){
auto pmem = m_baseAllocator.alloc(AllocSize!Pool); auto pmem = m_baseAllocator.alloc(AllocSize!Pool);
p = emplace!Pool(cast(Pool*)pmem.ptr); p = emplace!Pool(() @trusted { return cast(Pool*)pmem.ptr; } ());
p.data = m_baseAllocator.alloc(max(aligned_sz, m_poolSize)); p.data = m_baseAllocator.alloc(max(aligned_sz, m_poolSize));
p.remaining = p.data; p.remaining = p.data;
p.next = cast(Pool*)m_freePools; p.next = cast(Pool*)m_freePools;
@ -560,7 +560,7 @@ nothrow:
} }
this(size_t elem_size, Allocator base_allocator) this(size_t elem_size, Allocator base_allocator)
{ @safe {
assert(elem_size >= size_t.sizeof); assert(elem_size >= size_t.sizeof);
m_elemSize = elem_size; m_elemSize = elem_size;
m_baseAlloc = base_allocator; m_baseAlloc = base_allocator;
@ -576,13 +576,13 @@ nothrow:
} }
void[] alloc() void[] alloc()
{ @safe {
void[] mem; void[] mem;
if( m_firstFree ){ if( m_firstFree ){
auto slot = m_firstFree; auto slot = m_firstFree;
m_firstFree = slot.next; m_firstFree = slot.next;
slot.next = null; slot.next = null;
mem = (cast(void*)slot)[0 .. m_elemSize]; mem = () @trusted { return (cast(void*)slot)[0 .. m_elemSize]; } ();
debug m_nfree--; debug m_nfree--;
} else { } else {
mem = m_baseAlloc.alloc(m_elemSize); mem = m_baseAlloc.alloc(m_elemSize);
@ -800,7 +800,7 @@ unittest {
} }
private size_t alignedSize(size_t sz) nothrow private size_t alignedSize(size_t sz) nothrow
{ @safe {
return ((sz + Allocator.alignment - 1) / Allocator.alignment) * Allocator.alignment; return ((sz + Allocator.alignment - 1) / Allocator.alignment) * Allocator.alignment;
} }
@ -814,8 +814,8 @@ unittest {
} }
private void ensureValidMemory(void[] mem) nothrow private void ensureValidMemory(void[] mem) nothrow
{ @safe {
auto bytes = cast(ubyte[])mem; auto bytes = () @trusted { return cast(ubyte[])mem; } ();
swap(bytes[0], bytes[$-1]); swap(bytes[0], bytes[$-1]);
swap(bytes[0], bytes[$-1]); swap(bytes[0], bytes[$-1]);
} }