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

Commit

Permalink
Minor changes for effeciency to array finalization, as well as added …
Browse files Browse the repository at this point in the history
…callStructDtorsDuringGC to core.memory.
  • Loading branch information
Orvid committed Dec 12, 2014
1 parent cd1a9cb commit c424346
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 27 deletions.
10 changes: 5 additions & 5 deletions src/core/exception.d
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class StructFinalizeError : Error

@safe pure nothrow this( TypeInfo_Struct si, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
{
super( "Finalization error", file, line, next );
super( "Struct finalization error", file, line, next );
info = si;
}

Expand All @@ -215,7 +215,7 @@ unittest
assert(fe.file == __FILE__);
assert(fe.line == __LINE__ - 2);
assert(fe.next is null);
assert(fe.msg == "Finalization error");
assert(fe.msg == "Struct finalization error");
assert(fe.info == info);
}

Expand All @@ -224,7 +224,7 @@ unittest
assert(fe.file == __FILE__);
assert(fe.line == __LINE__ - 2);
assert(fe.next !is null);
assert(fe.msg == "Finalization error");
assert(fe.msg == "Struct finalization error");
assert(fe.info == info);
}

Expand All @@ -233,7 +233,7 @@ unittest
assert(fe.file == "hello");
assert(fe.line == 42);
assert(fe.next is null);
assert(fe.msg == "Finalization error");
assert(fe.msg == "Struct finalization error");
assert(fe.info == info);
}

Expand All @@ -242,7 +242,7 @@ unittest
assert(fe.file == "hello");
assert(fe.line == 42);
assert(fe.next !is null);
assert(fe.msg == "Finalization error");
assert(fe.msg == "Struct finalization error");
assert(fe.info == info);
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/memory.d
Original file line number Diff line number Diff line change
Expand Up @@ -761,3 +761,9 @@ struct GC
gc_runFinalizers( segment );
}
}

void callStructDtorsDuringGC(bool callThem)
{
static import rt.lifetime;
rt.lifetime.callStructDtorsDuringGC = callThem;
}
22 changes: 11 additions & 11 deletions src/gc/gc.d
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ 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, bool resetMemory) nothrow;
void rt_finalize_struct(void* p, bool resetMemory, bool fromGC) nothrow;
int rt_hasStructFinalizerInSegment(void* p, in void[] segment) nothrow;
void rt_finalize_array(void* p, bool resetMemory = true) nothrow;
void rt_finalize_array2(void* p, BlkInfo inf, bool resetMemory, bool fromGC) nothrow;
int rt_hasArrayFinalizerInSegment(void* p, in void[] segment) nothrow;
void rt_finalize2(void* p, bool det, bool resetMemory) nothrow;
int rt_hasFinalizerInSegment(void* p, in void[] segment) nothrow;
Expand Down Expand Up @@ -558,7 +558,7 @@ class GC
gcx.log_malloc(p, size);

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

Expand Down Expand Up @@ -1615,9 +1615,9 @@ struct Gcx
if (pool.structFinals.nbits && pool.structFinals.test(biti))
{
if (pool.appendable.nbits && pool.appendable.test(biti) && rt_hasArrayFinalizerInSegment(sentinel_add(p), segment))
rt_finalize_array(sentinel_add(p));
rt_finalize_array2(sentinel_add(p), BlkInfo(p, pool.bPageOffsets[pn] * PAGESIZE), true, true);
else if (rt_hasStructFinalizerInSegment(sentinel_add(p), segment))
rt_finalize_struct(sentinel_add(p), false);
rt_finalize_struct(sentinel_add(p), false, true);
else
continue;
}
Expand Down Expand Up @@ -1675,9 +1675,9 @@ struct Gcx
if (pool.structFinals.nbits && pool.structFinals.test(biti))
{
if (pool.appendable.nbits && pool.appendable.test(biti) && rt_hasArrayFinalizerInSegment(sentinel_add(p), segment))
rt_finalize_array(sentinel_add(p));
rt_finalize_array2(sentinel_add(p), BlkInfo(p, size), true, true);
else if (rt_hasStructFinalizerInSegment(sentinel_add(p), segment))
rt_finalize_struct(sentinel_add(p), false);
rt_finalize_struct(sentinel_add(p), false, true);
else
continue;
}
Expand Down Expand Up @@ -2680,9 +2680,9 @@ struct Gcx
if (pool.structFinals.nbits && pool.structFinals.testClear(biti))
{
if (pool.appendable.nbits && pool.appendable.test(biti))
rt_finalize_array(sentinel_add(p));
rt_finalize_array2(sentinel_add(p), BlkInfo(p, pool.bPageOffsets[pn] * PAGESIZE), true, true);
else
rt_finalize_struct(sentinel_add(p), false);
rt_finalize_struct(sentinel_add(p), false, true);
}
else if (pool.finals.nbits && pool.finals.testClear(biti))
rt_finalize2(sentinel_add(p), false, false);
Expand Down Expand Up @@ -2759,9 +2759,9 @@ struct Gcx
if (pool.structFinals.nbits && pool.structFinals.test(biti))
{
if (pool.appendable.nbits && pool.appendable.test(biti))
rt_finalize_array(sentinel_add(p));
rt_finalize_array2(sentinel_add(p), BlkInfo(p, size), true, true);
else
rt_finalize_struct(sentinel_add(p), false);
rt_finalize_struct(sentinel_add(p), false, true);
}
else if (pool.finals.nbits && pool.finals.test(biti))
rt_finalize2(sentinel_add(p), false, false);
Expand Down
40 changes: 29 additions & 11 deletions src/rt/lifetime.d
Original file line number Diff line number Diff line change
Expand Up @@ -1064,9 +1064,9 @@ 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;
bool needsTypeInfo = false;
if (auto si = cast(TypeInfo_Struct)ti)
{
{
if (si.xdtor !is null)
{
needsTypeInfo = true;
Expand Down Expand Up @@ -1104,9 +1104,9 @@ 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;
bool needsTypeInfo = false;
if (auto si = cast(TypeInfo_Struct)ti)
{
{
if (si.xdtor !is null)
{
needsTypeInfo = true;
Expand Down Expand Up @@ -1279,6 +1279,8 @@ extern (C) int rt_hasFinalizerInSegment(void* p, in void[] segment) nothrow
return false;
}

__gshared bool callStructDtorsDuringGC = true;

extern (C) int rt_hasStructFinalizerInSegment(void* p, in void[] segment) nothrow
{
if(!p)
Expand All @@ -1305,16 +1307,18 @@ extern (C) int rt_hasArrayFinalizerInSegment(void* p, in void[] segment) nothrow
return cast(size_t)(cast(void*)si.xdtor - segment.ptr) < segment.length;
}

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

if (fromGC && !callStructDtorsDuringGC)
return;

if(!p)
return;

size_t elementCount = void;
TypeInfo_Struct si = void;
BlkInfo inf = GC.query(p);
if(inf.size <= 256)
{
si = *cast(TypeInfo_Struct*)(inf.base + inf.size - SMALLPAD - size_t.sizeof);
Expand All @@ -1333,9 +1337,6 @@ extern (C) void rt_finalize_array(void* p, bool resetMemory = true) nothrow

try
{
// Mark it as finalized so that the GC doesn't attempt to
// finalize it again.
GC.clrAttr(p, BlkAttr.FINALIZE);
// Due to the fact that the delete operator calls destructors
// for arrays from the last element to the first, we maintain
// compatibility here by doing the same.
Expand All @@ -1360,10 +1361,27 @@ extern (C) void rt_finalize_array(void* p, bool resetMemory = true) nothrow
}
}

extern (C) void rt_finalize_struct(void* p, bool resetMemory = true) nothrow
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;

BlkInfo inf = GC.query(p);
// Mark it as finalized so that the GC doesn't attempt to
// finalize it again.
GC.clrAttr(p, BlkAttr.FINALIZE);
rt_finalize_array2(p, inf, resetMemory);
}

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

if (fromGC && !callStructDtorsDuringGC)
return;

if(!p)
return;

Expand Down

0 comments on commit c424346

Please sign in to comment.