47 changes: 47 additions & 0 deletions src/gc/structinfo.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Contains an array of struct infos used by the GC.
*
* Copyright: Copyright Digital Mars 2005 - 2013.
* License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
* Authors: Orvid King
*/

/* Copyright Digital Mars 2005 - 2013.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
module gc.structinfo;


import core.stdc.string;
import core.stdc.stdlib;
import core.exception : onOutOfMemoryError;

struct GCStructInfoArray
{
StructInfo* data = null;
size_t length = 0;

void Dtor() nothrow
{
if (data)
{
free(data);
data = null;
length = 0;
}
}

invariant()
{
}

void alloc(size_t nEntries) nothrow
{
this.length = nEntries;
data = cast(typeof(data[0])*)calloc(nEntries, data[0].sizeof);
if (!data)
onOutOfMemoryError();
}
}
1 change: 1 addition & 0 deletions src/object.di
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ class TypeInfo_Interface : TypeInfo
ClassInfo info;
}

alias TypeInfo_Struct StructInfo;
class TypeInfo_Struct : TypeInfo
{
string name;
Expand Down
5 changes: 5 additions & 0 deletions src/object_.d
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ 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
45 changes: 41 additions & 4 deletions src/rt/lifetime.d
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static import rt.tlsgc;

alias BlkInfo = GC.BlkInfo;
alias BlkAttr = GC.BlkAttr;
import core.exception : onOutOfMemoryError, onFinalizeError;
import core.exception : onOutOfMemoryError, onFinalizeError, onStructFinalizeError;

private
{
Expand Down Expand Up @@ -53,7 +53,6 @@ extern (C) void* _d_allocmemory(size_t sz)
return GC.malloc(sz);
}


/**
*
*/
Expand Down Expand Up @@ -1011,6 +1010,10 @@ extern (C) void[] _d_newarraymiT(const TypeInfo ti, size_t ndims, ...)
extern (C) void* _d_newitemT(TypeInfo ti)
{
auto size = ti.tsize; // array element size
auto size = ti.tsize; // array element size
auto baseFlags = !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0;
if (auto si = cast(StructInfo)ti)
baseFlags |= si.xdtor ? BlkAttr.STRUCT_FINALIZE : 0;

debug(PRINTF) printf("_d_newitemT(size = %d)\n", size);
/* not sure if we need this...
Expand All @@ -1019,7 +1022,7 @@ extern (C) void* _d_newitemT(TypeInfo ti)
else
{*/
// allocate a block to hold this item
auto ptr = GC.malloc(size, !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0, ti);
auto ptr = GC.malloc(size, baseFlags, ti);
debug(PRINTF) printf(" p = %p\n", ptr);
if(size == ubyte.sizeof)
*cast(ubyte*)ptr = 0;
Expand All @@ -1037,6 +1040,9 @@ extern (C) void* _d_newitemT(TypeInfo ti)
extern (C) void* _d_newitemiT(TypeInfo ti)
{
auto size = ti.tsize; // array element size
auto baseFlags = !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0;
if (auto si = cast(StructInfo)ti)
baseFlags |= si.xdtor ? BlkAttr.STRUCT_FINALIZE : 0;

debug(PRINTF) printf("_d_newitemiT(size = %d)\n", size);

Expand All @@ -1048,7 +1054,7 @@ extern (C) void* _d_newitemiT(TypeInfo ti)
auto isize = initializer.length;
auto q = initializer.ptr;

auto ptr = GC.malloc(size, !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0, ti);
auto ptr = GC.malloc(size, baseFlags, ti);
debug(PRINTF) printf(" p = %p\n", ptr);
if (isize == 1)
*cast(ubyte*)ptr = *cast(ubyte*)q;
Expand Down Expand Up @@ -1210,6 +1216,37 @@ 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
{
if(!p)
return false;

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

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

if(!p)
return;

try
{
if (inf.xdtor)
inf.xdtor(p); // call destructor

if(resetMemory)
{
ubyte[] w = cast(ubyte[])inf.m_init;
(cast(ubyte*) p)[0 .. w.length] = w[];
}
}
catch (Throwable e)
{
onStructFinalizeError(inf, e);
}
}

/**
*
Expand Down