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

Commit

Permalink
Merge pull request #343 from denis-sh/improve-rt.lifetime.rt_finalize
Browse files Browse the repository at this point in the history
Improve `rt.lifetime.rt_finalize`
  • Loading branch information
Alex Rønne Petersen committed Nov 15, 2012
2 parents 1171f44 + 8feb5f5 commit b3ffea5
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 71 deletions.
6 changes: 3 additions & 3 deletions src/gc/gcx.d
Expand Up @@ -97,7 +97,7 @@ private
}
private
{
extern (C) void rt_finalize_gc(void* p);
extern (C) void rt_finalize2(void* p, bool det, bool resetMemory);

extern (C) void thread_suspendAll();
extern (C) void thread_resumeAll();
Expand Down Expand Up @@ -2587,7 +2587,7 @@ struct Gcx

sentinel_Invariant(sentinel_add(p));
if (pool.finals.nbits && pool.finals.testClear(biti))
rt_finalize_gc(sentinel_add(p));
rt_finalize2(sentinel_add(p), false, false);
clrBits(pool, biti, BlkAttr.ALL_BITS ^ BlkAttr.FINALIZE);

debug(COLLECT_PRINTF) printf("\tcollecting big %p\n", p);
Expand Down Expand Up @@ -2659,7 +2659,7 @@ struct Gcx

pool.freebits.set(biti);
if (pool.finals.nbits && pool.finals.test(biti))
rt_finalize_gc(sentinel_add(p));
rt_finalize2(sentinel_add(p), false, false);
toClear |= GCBits.BITS_1 << clearIndex;

List *list = cast(List *)p;
Expand Down
100 changes: 32 additions & 68 deletions src/rt/lifetime.d
Expand Up @@ -1212,86 +1212,50 @@ extern (C) CollectHandler rt_getCollectHandler()
/**
*
*/
extern (C) void rt_finalize(void* p, bool det = true)
extern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true)
{
debug(PRINTF) printf("rt_finalize(p = %p)\n", p);
debug(PRINTF) printf("rt_finalize2(p = %p)\n", p);

if (p)
{
ClassInfo** pc = cast(ClassInfo**)p;
auto ppv = cast(void**) p;
if(!p || !*ppv)
return;

if (*pc)
auto pc = cast(ClassInfo*) *ppv;
try
{
if (det || collectHandler is null || collectHandler(cast(Object) p))
{
ClassInfo c = **pc;
byte[] w = c.init;

try
{
if (det || collectHandler is null || collectHandler(cast(Object)p))
{
do
{
if (c.destructor)
{
fp_t fp = cast(fp_t)c.destructor;
(*fp)(cast(Object)p); // call destructor
}
c = c.base;
} while (c);
}
if ((cast(void**)p)[1]) // if monitor is not null
_d_monitordelete(cast(Object)p, det);
(cast(byte*) p)[0 .. w.length] = w[];
}
catch (Throwable e)
auto c = *pc;
do
{
onFinalizeError(**pc, e);
}
finally
{
*pc = null; // zero vptr
if (c.destructor)
(cast(fp_t) c.destructor)(cast(Object) p); // call destructor
}
while ((c = c.base) !is null);
}
}
}

/**
* An optimized version of rt_finalize that assumes it's being called from
* the garbage collector and avoids wasting time on things that are
* irrelevant in this case.
*/
extern (C) void rt_finalize_gc(void* p)
{
debug(PRINTF) printf("rt_finalize_gc(p = %p)\n", p);

ClassInfo** pc = cast(ClassInfo**)p;

if (*pc)
{
ClassInfo c = **pc;
if (ppv[1]) // if monitor is not null
_d_monitordelete(cast(Object) p, det);

try
{
if (collectHandler is null || collectHandler(cast(Object)p))
{
do
{
if (c.destructor)
{
fp_t fp = cast(fp_t)c.destructor;
(*fp)(cast(Object)p); // call destructor
}
c = c.base;
} while (c);
}
if ((cast(void**)p)[1]) // if monitor is not null
_d_monitordelete(cast(Object)p, false);
}
catch (Throwable e)
if(resetMemory)
{
onFinalizeError(**pc, e);
byte[] w = (*pc).init;
(cast(byte*) p)[0 .. w.length] = w[];
}
}
catch (Throwable e)
{
onFinalizeError(*pc, e);
}
finally
{
*ppv = null; // zero vptr even if `resetMemory` is false
}
}

extern (C) void rt_finalize(void* p, bool det = true)
{
rt_finalize2(p, det, true);
}


Expand Down

0 comments on commit b3ffea5

Please sign in to comment.