Annotate FreeListRef safe as far as possible.
This commit is contained in:
parent
3a5975f046
commit
9df6874a55
|
@ -633,15 +633,15 @@ struct FreeListObjectAlloc(T, bool USE_GC = true, bool INIT = true, EXTRA = void
|
||||||
auto ret = s_firstFree;
|
auto ret = s_firstFree;
|
||||||
s_firstFree = s_firstFree.next;
|
s_firstFree = s_firstFree.next;
|
||||||
ret.next = null;
|
ret.next = null;
|
||||||
mem = (cast(void*)ret)[0 .. ElemSize];
|
mem = () @trusted { return (cast(void*)ret)[0 .. ElemSize]; } ();
|
||||||
} else {
|
} else {
|
||||||
//logInfo("alloc %s/%d", T.stringof, ElemSize);
|
//logInfo("alloc %s/%d", T.stringof, ElemSize);
|
||||||
mem = manualAllocator().alloc(ElemSlotSize);
|
mem = manualAllocator().alloc(ElemSlotSize);
|
||||||
static if( hasIndirections!T ) GC.addRange(mem.ptr, ElemSlotSize);
|
static if( hasIndirections!T ) () @trusted { GC.addRange(mem.ptr, ElemSlotSize); } ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (INIT) return cast(TR)internalEmplace!(Unqual!T)(mem, args); // FIXME: this emplace has issues with qualified types, but Unqual!T may result in the wrong constructor getting called.
|
static if (INIT) return cast(TR)internalEmplace!(Unqual!T)(mem, args); // FIXME: this emplace has issues with qualified types, but Unqual!T may result in the wrong constructor getting called.
|
||||||
else return cast(TR)mem.ptr;
|
else return () @trusted { return cast(TR)mem.ptr; } ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free(TR obj)
|
static void free(TR obj)
|
||||||
|
@ -697,7 +697,7 @@ struct FreeListRef(T, bool INIT = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
~this()
|
~this()
|
||||||
{
|
@safe {
|
||||||
//if( m_object ) logInfo("~this!%s(): %d", T.stringof, this.refCount);
|
//if( m_object ) logInfo("~this!%s(): %d", T.stringof, this.refCount);
|
||||||
//if( m_object ) logInfo("ref %s destructor %d", T.stringof, refCount);
|
//if( m_object ) logInfo("ref %s destructor %d", T.stringof, refCount);
|
||||||
//else logInfo("ref %s destructor %d", T.stringof, 0);
|
//else logInfo("ref %s destructor %d", T.stringof, 0);
|
||||||
|
@ -707,7 +707,7 @@ struct FreeListRef(T, bool INIT = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
this(this)
|
this(this)
|
||||||
{
|
@safe {
|
||||||
checkInvariants();
|
checkInvariants();
|
||||||
if( m_object ){
|
if( m_object ){
|
||||||
//if( m_object ) logInfo("this!%s(this): %d", T.stringof, this.refCount);
|
//if( m_object ) logInfo("this!%s(this): %d", T.stringof, this.refCount);
|
||||||
|
@ -716,7 +716,7 @@ struct FreeListRef(T, bool INIT = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
void opAssign(FreeListRef other)
|
void opAssign(FreeListRef other)
|
||||||
{
|
@safe {
|
||||||
clear();
|
clear();
|
||||||
m_object = other.m_object;
|
m_object = other.m_object;
|
||||||
if( m_object ){
|
if( m_object ){
|
||||||
|
@ -726,11 +726,11 @@ struct FreeListRef(T, bool INIT = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
@safe {
|
||||||
checkInvariants();
|
checkInvariants();
|
||||||
if (m_object) {
|
if (m_object) {
|
||||||
if (--this.refCount == 0)
|
if (--this.refCount == 0)
|
||||||
ObjAlloc.free(m_object);
|
() @trusted { ObjAlloc.free(m_object); } ();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_object = null;
|
m_object = null;
|
||||||
|
@ -742,7 +742,7 @@ struct FreeListRef(T, bool INIT = true)
|
||||||
alias get this;
|
alias get this;
|
||||||
|
|
||||||
private @property ref int refCount()
|
private @property ref int refCount()
|
||||||
const {
|
@trusted const {
|
||||||
auto ptr = cast(ubyte*)cast(void*)m_object;
|
auto ptr = cast(ubyte*)cast(void*)m_object;
|
||||||
ptr += ElemSize;
|
ptr += ElemSize;
|
||||||
return *cast(int*)ptr;
|
return *cast(int*)ptr;
|
||||||
|
@ -755,6 +755,16 @@ struct FreeListRef(T, bool INIT = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@safe unittest {
|
||||||
|
static final class C {
|
||||||
|
@safe this() {}
|
||||||
|
@safe ~this() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto p = new C;
|
||||||
|
auto r = FreeListRef!C();
|
||||||
|
}
|
||||||
|
|
||||||
private void* extractUnalignedPointer(void* base) nothrow
|
private void* extractUnalignedPointer(void* base) nothrow
|
||||||
{
|
{
|
||||||
ubyte misalign = *(cast(ubyte*)base-1);
|
ubyte misalign = *(cast(ubyte*)base-1);
|
||||||
|
@ -823,20 +833,19 @@ private void ensureValidMemory(void[] mem) nothrow
|
||||||
/// See issue #14194
|
/// See issue #14194
|
||||||
private T internalEmplace(T, Args...)(void[] chunk, auto ref Args args)
|
private T internalEmplace(T, Args...)(void[] chunk, auto ref Args args)
|
||||||
if (is(T == class))
|
if (is(T == class))
|
||||||
in {
|
{
|
||||||
import std.string, std.format;
|
import std.string, std.format;
|
||||||
assert(chunk.length >= T.sizeof,
|
assert(chunk.length >= T.sizeof,
|
||||||
format("emplace: Chunk size too small: %s < %s size = %s",
|
format("emplace: Chunk size too small: %s < %s size = %s",
|
||||||
chunk.length, T.stringof, T.sizeof));
|
chunk.length, T.stringof, T.sizeof));
|
||||||
assert((cast(size_t) chunk.ptr) % T.alignof == 0,
|
assert((cast(size_t) chunk.ptr) % T.alignof == 0,
|
||||||
format("emplace: Misaligned memory block (0x%X): it must be %s-byte aligned for type %s", chunk.ptr, T.alignof, T.stringof));
|
format("emplace: Misaligned memory block (0x%X): it must be %s-byte aligned for type %s", &chunk[0], T.alignof, T.stringof));
|
||||||
|
|
||||||
} body {
|
|
||||||
enum classSize = __traits(classInstanceSize, T);
|
enum classSize = __traits(classInstanceSize, T);
|
||||||
auto result = cast(T) chunk.ptr;
|
auto result = () @trusted { return cast(T) chunk.ptr; } ();
|
||||||
|
|
||||||
// Initialize the object in its pre-ctor state
|
// Initialize the object in its pre-ctor state
|
||||||
chunk[0 .. classSize] = typeid(T).init[];
|
() @trusted { chunk[0 .. classSize] = typeid(T).init[]; } ();
|
||||||
|
|
||||||
// Call the ctor if any
|
// Call the ctor if any
|
||||||
static if (is(typeof(result.__ctor(args))))
|
static if (is(typeof(result.__ctor(args))))
|
||||||
|
@ -856,7 +865,7 @@ in {
|
||||||
|
|
||||||
/// Dittor
|
/// Dittor
|
||||||
private auto internalEmplace(T, Args...)(void[] chunk, auto ref Args args)
|
private auto internalEmplace(T, Args...)(void[] chunk, auto ref Args args)
|
||||||
if (!is(T == class))
|
@safe if (!is(T == class))
|
||||||
in {
|
in {
|
||||||
import std.string, std.format;
|
import std.string, std.format;
|
||||||
assert(chunk.length >= T.sizeof,
|
assert(chunk.length >= T.sizeof,
|
||||||
|
@ -866,7 +875,7 @@ in {
|
||||||
format("emplace: Misaligned memory block (0x%X): it must be %s-byte aligned for type %s", chunk.ptr, T.alignof, T.stringof));
|
format("emplace: Misaligned memory block (0x%X): it must be %s-byte aligned for type %s", chunk.ptr, T.alignof, T.stringof));
|
||||||
|
|
||||||
} body {
|
} body {
|
||||||
return emplace(cast(T*)chunk.ptr, args);
|
return emplace(() @trusted { return cast(T*)chunk.ptr; } (), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logDebug_(ARGS...)(string msg, ARGS args) {}
|
private void logDebug_(ARGS...)(string msg, ARGS args) {}
|
||||||
|
|
Loading…
Reference in a new issue