Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
As discussed on the PR, removed StructInfo, and replaced all uses of …
Browse files Browse the repository at this point in the history
…it with TypeInfo_Struct.

I also made the runtime entirely responsible for managing the type info of a finalizable struct. Previously the GC first had to retrieve this info before calling the runtime to do the finalization, even though it's the runtime that determined where to put the type info.
  • Loading branch information
Orvid committed Dec 12, 2014
1 parent edd5666 commit a54dc00
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 78 deletions.
12 changes: 6 additions & 6 deletions src/core/exception.d
Expand Up @@ -186,14 +186,14 @@ unittest
*/
class StructFinalizeError : Error
{
StructInfo info;
TypeInfo_Struct info;

@safe pure nothrow this( StructInfo si, Throwable next, string file = __FILE__, size_t line = __LINE__ )
@safe pure nothrow this( TypeInfo_Struct si, Throwable next, string file = __FILE__, size_t line = __LINE__ )
{
this(si, file, line, next);
}

@safe pure nothrow this( StructInfo si, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
@safe pure nothrow this( TypeInfo_Struct si, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
{
super( "Finalization error", file, line, next );
info = si;
Expand All @@ -207,7 +207,7 @@ class StructFinalizeError : Error

unittest
{
StructInfo info = new StructInfo;
TypeInfo_Struct info = new TypeInfo_Struct;
info.name = "testInfo";

{
Expand Down Expand Up @@ -557,15 +557,15 @@ extern (C) void onFinalizeError( ClassInfo info, Throwable e, string file = __FI
* A callback for struct finalize errors in D. A StructFinalizeError will be thrown.
*
* Params:
* info = The StructInfo instance for the object that failed finalization.
* info = The TypeInfo_Struct instance for the object that failed finalization.
* e = The exception thrown during finalization.
* file = The name of the file that signaled this error.
* line = The line number on which this error occurred.
*
* Throws:
* FinalizeError.
*/
extern (C) void onStructFinalizeError( StructInfo info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow
extern (C) void onStructFinalizeError( TypeInfo_Struct info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow
{
throw new StructFinalizeError( info, file, line, e );
}
Expand Down
44 changes: 19 additions & 25 deletions src/gc/gc.d
Expand Up @@ -128,8 +128,8 @@ private
{
// to allow compilation of this module without access to the rt package,
// make these functions available from rt.lifetime
void rt_finalize_struct(void* p, StructInfo inf, bool resetMemory) nothrow;
int rt_hasStructFinalizerInSegment(void* p, StructInfo inf, in void[] segment) nothrow;
void rt_finalize_struct(void* p, bool resetMemory) nothrow;
int rt_hasStructFinalizerInSegment(void* p, in void[] segment) nothrow;
void rt_finalize_array(void* p, bool resetMemory = true) nothrow;
int rt_hasArrayFinalizerInSegment(void* p, in void[] segment) nothrow;
void rt_finalize2(void* p, bool det, bool resetMemory) nothrow;
Expand Down Expand Up @@ -378,7 +378,7 @@ class GC
/**
*
*/
uint setAttr(void* p, uint mask, StructInfo inf = null) nothrow
uint setAttr(void* p, uint mask, TypeInfo_Struct inf = null) nothrow
{
if (!p)
{
Expand Down Expand Up @@ -556,12 +556,12 @@ class GC
alloc_size = size;
}
gcx.log_malloc(p, size);

if (ti)
gcx.setBits(pool, cast(size_t)(p - pool.baseAddr) >> pool.shiftBy, bits, cast(StructInfo)ti.next);
gcx.setBits(pool, cast(size_t)(p - pool.baseAddr) >> pool.shiftBy, bits, cast(TypeInfo_Struct)ti.next);
else
gcx.setBits(pool, cast(size_t)(p - pool.baseAddr) >> pool.shiftBy, bits);

return p;
}

Expand Down Expand Up @@ -668,7 +668,7 @@ class GC
if (bits)
{
gcx.clrBits(pool, biti, ~BlkAttr.NONE);
gcx.setBits(pool, biti, bits, cast(StructInfo)ti);
gcx.setBits(pool, biti, bits, cast(TypeInfo_Struct)ti);
}
else
{
Expand Down Expand Up @@ -720,7 +720,7 @@ class GC
{
immutable biti = cast(size_t)(p - pool.baseAddr) >> pool.shiftBy;
gcx.clrBits(pool, biti, ~BlkAttr.NONE);
gcx.setBits(pool, biti, bits, cast(StructInfo)ti);
gcx.setBits(pool, biti, bits, cast(TypeInfo_Struct)ti);
}
alloc_size = newsz * PAGESIZE;
return p;
Expand All @@ -737,7 +737,7 @@ class GC
if (bits)
{
gcx.clrBits(pool, biti, ~BlkAttr.NONE);
gcx.setBits(pool, biti, bits, cast(StructInfo)ti);
gcx.setBits(pool, biti, bits, cast(TypeInfo_Struct)ti);
}
else
{
Expand Down Expand Up @@ -1616,13 +1616,10 @@ struct Gcx
{
if (pool.appendable.nbits && pool.appendable.test(biti) && rt_hasArrayFinalizerInSegment(sentinel_add(p), segment))
rt_finalize_array(sentinel_add(p));
else if (rt_hasStructFinalizerInSegment(sentinel_add(p), segment))
rt_finalize_struct(sentinel_add(p), false);
else
{
auto si = *cast(StructInfo*)(sentinel_add(p) + pool.getSize(p) - size_t.sizeof);
if (!rt_hasStructFinalizerInSegment(sentinel_add(p), si, segment))
continue;
rt_finalize_struct(sentinel_add(p), si, false);
}
continue;
}
else if (!pool.finals.nbits || !pool.finals.test(biti) || !rt_hasFinalizerInSegment(sentinel_add(p), segment))
continue;
Expand Down Expand Up @@ -1679,13 +1676,10 @@ struct Gcx
{
if (pool.appendable.nbits && pool.appendable.test(biti) && rt_hasArrayFinalizerInSegment(sentinel_add(p), segment))
rt_finalize_array(sentinel_add(p));
else if (rt_hasStructFinalizerInSegment(sentinel_add(p), segment))
rt_finalize_struct(sentinel_add(p), false);
else
{
auto si = *cast(StructInfo*)(sentinel_add(p) + pool.getSize(p) - size_t.sizeof);
if (!rt_hasStructFinalizerInSegment(sentinel_add(p), si, segment))
continue;
rt_finalize_struct(sentinel_add(p), si, false);
}
continue;
}
else if (!pool.finals.nbits || !pool.finals.test(biti) || !rt_hasFinalizerInSegment(sentinel_add(p), segment))
continue;
Expand Down Expand Up @@ -2688,7 +2682,7 @@ struct Gcx
if (pool.appendable.nbits && pool.appendable.test(biti))
rt_finalize_array(sentinel_add(p));
else
rt_finalize_struct(sentinel_add(p), *cast(StructInfo*)(sentinel_add(p) + pool.getSize(p) - size_t.sizeof), false);
rt_finalize_struct(sentinel_add(p), false);
}
else if (pool.finals.nbits && pool.finals.testClear(biti))
rt_finalize2(sentinel_add(p), false, false);
Expand Down Expand Up @@ -2767,7 +2761,7 @@ struct Gcx
if (pool.appendable.nbits && pool.appendable.test(biti))
rt_finalize_array(sentinel_add(p));
else
rt_finalize_struct(sentinel_add(p), *cast(StructInfo*)(sentinel_add(p) + pool.getSize(p) - size_t.sizeof), false);
rt_finalize_struct(sentinel_add(p), false);
}
else if (pool.finals.nbits && pool.finals.test(biti))
rt_finalize2(sentinel_add(p), false, false);
Expand Down Expand Up @@ -2935,7 +2929,7 @@ struct Gcx
/**
*
*/
void setBits(Pool* pool, size_t biti, uint mask, StructInfo inf = null) nothrow
void setBits(Pool* pool, size_t biti, uint mask, TypeInfo_Struct inf = null) nothrow
in
{
assert(pool);
Expand All @@ -2947,7 +2941,7 @@ struct Gcx
immutable dataIndex = 1 + (biti >> GCBits.BITS_SHIFT);
immutable bitOffset = biti & GCBits.BITS_MASK;
immutable orWith = GCBits.BITS_1 << bitOffset;

if (inf !is null && inf.xdtor !is null)
{
if (!pool.structFinals.nbits)
Expand Down
1 change: 0 additions & 1 deletion src/object.di
Expand Up @@ -190,7 +190,6 @@ class TypeInfo_Interface : TypeInfo
ClassInfo info;
}

alias TypeInfo_Struct StructInfo;
class TypeInfo_Struct : TypeInfo
{
string name;
Expand Down
5 changes: 0 additions & 5 deletions src/object_.d
Expand Up @@ -194,11 +194,6 @@ struct Interface
*/
alias TypeInfo_Class Classinfo;

/**
* Runtime type information about a struct.
*/
alias TypeInfo_Struct StructInfo;

/**
* Array of pairs giving the offset and type information for each
* member in an aggregate.
Expand Down
68 changes: 27 additions & 41 deletions src/rt/lifetime.d
Expand Up @@ -170,23 +170,7 @@ extern (C) void _d_delstruct(void** p, TypeInfo_Struct inf)
if (*p)
{
debug(PRINTF) printf("_d_delstruct(%p, %p)\n", *p, cast(void*)inf);

inf.xdtor(*p);

GC.free(*p);
*p = null;
}
}

/**
*
*/
extern (C) void _d_delstruct(void** p, StructInfo inf)
{
if (*p)
{
debug(PRINTF) printf("_d_delstruct(%p, %p)\n", *p, cast(void*)inf);
rt_finalize_struct(*p, inf);
rt_finalize_struct(*p);
GC.free(*p);
*p = null;
}
Expand Down Expand Up @@ -235,7 +219,7 @@ private class ArrayAllocLengthLock
bool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, const TypeInfo ti, size_t oldlength = ~0) pure nothrow
{
bool needToSetTypeInfo = false;
if (auto si = cast(const StructInfo)ti.next)
if (auto si = cast(const TypeInfo_Struct)ti.next)
{
if (si.xdtor)
{
Expand Down Expand Up @@ -277,8 +261,8 @@ bool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, co
}
if (needToSetTypeInfo)
{
auto typeInfo = cast(StructInfo*)(info.base + info.size - SMALLPAD - size_t.sizeof);
*typeInfo = cast(StructInfo)ti.next;
auto typeInfo = cast(TypeInfo_Struct*)(info.base + info.size - SMALLPAD - size_t.sizeof);
*typeInfo = cast(TypeInfo_Struct)ti.next;
}
}
else if(info.size < PAGESIZE)
Expand Down Expand Up @@ -316,8 +300,8 @@ bool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, co
}
if (needToSetTypeInfo)
{
auto typeInfo = cast(StructInfo*)(info.base + info.size - MEDPAD - size_t.sizeof);
*typeInfo = cast(StructInfo)ti.next;
auto typeInfo = cast(TypeInfo_Struct*)(info.base + info.size - MEDPAD - size_t.sizeof);
*typeInfo = cast(TypeInfo_Struct)ti.next;
}
}
else
Expand Down Expand Up @@ -355,8 +339,8 @@ bool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, co
}
if (needToSetTypeInfo)
{
auto typeInfo = cast(StructInfo*)(info.base + size_t.sizeof);
*typeInfo = cast(StructInfo)ti.next;
auto typeInfo = cast(TypeInfo_Struct*)(info.base + size_t.sizeof);
*typeInfo = cast(TypeInfo_Struct)ti.next;
}
}
return true; // resize succeeded
Expand All @@ -378,7 +362,7 @@ void *__arrayStart(BlkInfo info) nothrow pure
size_t __arrayPad(size_t size, const TypeInfo ti) nothrow pure @trusted
{
size_t typeInfoSize = 0;
if (auto si = cast(const StructInfo)ti.next)
if (auto si = cast(const TypeInfo_Struct)ti.next)
{
if (si.xdtor)
typeInfoSize = size_t.sizeof;
Expand Down Expand Up @@ -1056,7 +1040,7 @@ extern (C) void* _d_newitemT(TypeInfo ti)
auto size = ti.tsize; // array element size
auto baseFlags = !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0;
bool needsTypeInfo = false;
if (auto si = cast(StructInfo)ti)
if (auto si = cast(TypeInfo_Struct)ti)
{
if (si.xdtor !is null)
{
Expand Down Expand Up @@ -1096,7 +1080,7 @@ extern (C) void* _d_newitemiT(TypeInfo ti)
auto size = ti.tsize; // array element size
auto baseFlags = !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0;
bool needsTypeInfo = false;
if (auto si = cast(StructInfo)ti)
if (auto si = cast(TypeInfo_Struct)ti)
{
if (si.xdtor !is null)
{
Expand Down Expand Up @@ -1270,11 +1254,12 @@ extern (C) int rt_hasFinalizerInSegment(void* p, in void[] segment) nothrow
return false;
}

extern (C) int rt_hasStructFinalizerInSegment(void* p, StructInfo inf, in void[] segment) nothrow
extern (C) int rt_hasStructFinalizerInSegment(void* p, in void[] segment) nothrow
{
if(!p)
return false;


auto inf = *cast(TypeInfo_Struct*)(p + GC.sizeOf(p) - size_t.sizeof);
return cast(size_t)(cast(void*)inf.xdtor - segment.ptr) < segment.length;
}

Expand All @@ -1283,41 +1268,41 @@ extern (C) int rt_hasArrayFinalizerInSegment(void* p, in void[] segment) nothrow
if(!p)
return false;

StructInfo si = void;
TypeInfo_Struct si = void;
BlkInfo inf = GC.query(p);
if(inf.size <= 256)
si = *cast(StructInfo*)(inf.base + inf.size - SMALLPAD - size_t.sizeof);
si = *cast(TypeInfo_Struct*)(inf.base + inf.size - SMALLPAD - size_t.sizeof);
else if (inf.size < PAGESIZE)
si = *cast(StructInfo*)(inf.base + inf.size - MEDPAD - size_t.sizeof);
si = *cast(TypeInfo_Struct*)(inf.base + inf.size - MEDPAD - size_t.sizeof);
else
si = *cast(StructInfo*)(inf.base + size_t.sizeof);
si = *cast(TypeInfo_Struct*)(inf.base + size_t.sizeof);

return cast(size_t)(cast(void*)si.xdtor - segment.ptr) < segment.length;
}

extern (C) void rt_finalize_array(void* p, bool resetMemory = true) nothrow
{
debug(PRINTF) printf("rt_finalize_array(p = %p)\n", p);

if(!p)
return;

size_t elementCount = void;
StructInfo si = void;
TypeInfo_Struct si = void;
BlkInfo inf = GC.query(p);
if(inf.size <= 256)
{
si = *cast(StructInfo*)(inf.base + inf.size - SMALLPAD - size_t.sizeof);
si = *cast(TypeInfo_Struct*)(inf.base + inf.size - SMALLPAD - size_t.sizeof);
elementCount = *cast(ubyte*)(inf.base + inf.size - SMALLPAD) / si.tsize;
}
else if (inf.size < PAGESIZE)
{
si = *cast(StructInfo*)(inf.base + inf.size - MEDPAD - size_t.sizeof);
si = *cast(TypeInfo_Struct*)(inf.base + inf.size - MEDPAD - size_t.sizeof);
elementCount = *cast(ushort*)(inf.base + inf.size - MEDPAD) / si.tsize;
}
else
{
si = *cast(StructInfo*)(inf.base + size_t.sizeof);
si = *cast(TypeInfo_Struct*)(inf.base + size_t.sizeof);
elementCount = *cast(size_t*)(inf.base) / si.tsize;
}

Expand All @@ -1333,7 +1318,7 @@ extern (C) void rt_finalize_array(void* p, bool resetMemory = true) nothrow
for (size_t i = 0; i < elementCount; i++, curP -= si.tsize)
{
si.xdtor(curP); // call destructor

if(resetMemory)
{
ubyte[] w = cast(ubyte[])si.m_init;
Expand All @@ -1350,21 +1335,22 @@ extern (C) void rt_finalize_array(void* p, bool resetMemory = true) nothrow
}
}

extern (C) void rt_finalize_struct(void* p, StructInfo inf, bool resetMemory = true) nothrow
extern (C) void rt_finalize_struct(void* p, bool resetMemory = true) nothrow
{
debug(PRINTF) printf("rt_finalize_struct(p = %p)\n", p);

if(!p)
return;

auto inf = *cast(TypeInfo_Struct*)(p + GC.sizeOf(p) - size_t.sizeof);
try
{
// Mark it as finalized so that the GC doesn't attempt to
// finalize it again.
GC.clrAttr(p, BlkAttr.FINALIZE);
if (inf.xdtor)
inf.xdtor(p); // call destructor

if(resetMemory)
{
ubyte[] w = cast(ubyte[])inf.m_init;
Expand Down

0 comments on commit a54dc00

Please sign in to comment.