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

Commit

Permalink
configure callStructDtorsDuringGC through rt_configOption
Browse files Browse the repository at this point in the history
  • Loading branch information
rainers committed Dec 12, 2014
1 parent ac403db commit daf7e62
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 34 deletions.
2 changes: 0 additions & 2 deletions src/core/memory.d
Original file line number Diff line number Diff line change
Expand Up @@ -763,5 +763,3 @@ struct GC
gc_runFinalizers( segment );
}
}

__gshared bool callStructDtorsDuringGC = true;
2 changes: 2 additions & 0 deletions src/rt/dmain2.d
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ extern (C) void _STI_critical_init();
extern (C) void _STD_critical_term();
extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void lifetime_init();
extern (C) void rt_moduleCtor();
extern (C) void rt_moduleTlsCtor();
extern (C) void rt_moduleDtor();
Expand Down Expand Up @@ -166,6 +167,7 @@ extern (C) int rt_init()
initSections();
gc_init();
initStaticDataGC();
lifetime_init();
rt_moduleCtor();
rt_moduleTlsCtor();
return 1;
Expand Down
81 changes: 49 additions & 32 deletions src/rt/lifetime.d
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ private
}
}

private immutable bool callStructDtorsDuringGC;

extern (C) void lifetime_init()
{
// this is run before static ctors, so it is safe to modify immutables
import rt.config;
if (string s = rt_configOption("callStructDtorsDuringGC"))
cast() callStructDtorsDuringGC = s[0] == '1' || s[0] == 'y' || s[0] == 'Y';
else
cast() callStructDtorsDuringGC = true;
}

/**
*
Expand Down Expand Up @@ -203,6 +214,9 @@ inout(TypeInfo) unqualify(inout(TypeInfo) cti) pure nothrow @nogc
// size used to store the TypeInfo at the end of an allocation for structs that have a destructor
size_t structTypeInfoSize(const TypeInfo ti) pure nothrow @nogc
{
if (!callStructDtorsDuringGC)
return 0;

if (ti && typeid(ti) is typeid(TypeInfo_Struct)) // avoid a complete dynamic type cast
{
auto sti = cast(TypeInfo_Struct)cast(void*)ti;
Expand Down Expand Up @@ -1358,9 +1372,6 @@ void finalize_array2(void* p, size_t size, bool resetMemory = true) nothrow
{
debug(PRINTF) printf("rt_finalize_array2(p = %p)\n", p);

if (!callStructDtorsDuringGC)
return;

TypeInfo_Struct si = void;
if(size <= 256)
{
Expand Down Expand Up @@ -1415,9 +1426,6 @@ void finalize_struct(void* p, size_t size, bool resetMemory = true) nothrow
{
debug(PRINTF) printf("finalize_struct(p = %p)\n", p);

if (!callStructDtorsDuringGC)
return;

auto ti = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);
try
{
Expand Down Expand Up @@ -2683,47 +2691,56 @@ unittest
delete arr1;
assert(dtorCount == 7);

dtorCount = 0;
S1* s2 = new S1;
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 1);
GC.free(s2);
if (callStructDtorsDuringGC)
{
dtorCount = 0;
S1* s2 = new S1;
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 1);
GC.free(s2);

dtorCount = 0;
const(S1)* s3 = new const(S1);
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 1);
GC.free(cast(void*)s3);
dtorCount = 0;
const(S1)* s3 = new const(S1);
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 1);
GC.free(cast(void*)s3);

dtorCount = 0;
shared(S1)* s4 = new shared(S1);
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 1);
GC.free(cast(void*)s4);
dtorCount = 0;
shared(S1)* s4 = new shared(S1);
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 1);
GC.free(cast(void*)s4);

dtorCount = 0;
const(S1)[] carr1 = new const(S1)[5];
BlkInfo blkinf1 = GC.query(carr1.ptr);
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 5);
GC.free(blkinf1.base);
dtorCount = 0;
const(S1)[] carr1 = new const(S1)[5];
BlkInfo blkinf1 = GC.query(carr1.ptr);
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 5);
GC.free(blkinf1.base);
}

dtorCount = 0;
S1[] arr2 = new S1[10];
arr2.length = 6;
arr2.assumeSafeAppend;
assert(dtorCount == 4); // destructors run explicitely?

dtorCount = 0;
BlkInfo blkinf = GC.query(arr2.ptr);
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 6);
GC.free(blkinf.base);
if (callStructDtorsDuringGC)
{
dtorCount = 0;
BlkInfo blkinf = GC.query(arr2.ptr);
GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
assert(dtorCount == 6);
GC.free(blkinf.base);
}
}

// test struct finalizers exception handling
unittest
{
if (!callStructDtorsDuringGC)
return;

import core.exception;
static struct S1
{
Expand Down

0 comments on commit daf7e62

Please sign in to comment.