Expand Up
@@ -667,13 +667,14 @@ extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) /+nothrow+/
}
}
package bool hasPostblit(in TypeInfo ti)
{
return (&ti.postblit).funcptr ! is &TypeInfo .postblit;
}
void __doPostblit (void * ptr, size_t len, const TypeInfo ti)
{
// optimize out any type info that does not need postblit.
// if((&ti.postblit).funcptr is &TypeInfo.postblit) // compiler doesn't like this
auto fptr = &ti.postblit;
if (fptr.funcptr is &TypeInfo .postblit)
// postblit has not been overridden, no point in looping.
if (! hasPostblit(ti))
return ;
if (auto tis = cast (TypeInfo_Struct )ti)
Expand Down
Expand Up
@@ -1051,83 +1052,43 @@ extern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims)
}
/**
* Allocate a non-array item.
* Allocate an uninitialized non-array item.
* This is an optimization to avoid things needed for arrays like the __arrayPad(size).
*/
extern (C ) void * _d_newitemT(TypeInfo _ti)
extern (C ) void * _d_newitemU(in TypeInfo _ti)
{
auto ti = unqualify(_ti);
auto size = ti.tsize; // array element size
auto baseFlags = ! (ti.flags & 1 ) ? BlkAttr.NO_SCAN : 0 ;
size_t typeInfoSize = structTypeInfoSize(ti);
size += typeInfoSize; // Need space for the type info
if (typeInfoSize)
baseFlags |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE ;
auto flags = ! (ti.flags & 1 ) ? BlkAttr.NO_SCAN : 0 ;
immutable tiSize = structTypeInfoSize(ti);
immutable size = ti.tsize + tiSize;
if (tiSize)
flags |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE ;
debug (PRINTF ) printf(" _d_newitemT(size = %d)\n " , size);
/* not sure if we need this...
* if (length == 0 || size == 0)
result = null;
else
{*/
// allocate a block to hold this item
auto blkInf = GC .qalloc(size, baseFlags, ti);
auto ptr = blkInf.base;
debug (PRINTF ) printf(" p = %p\n " , ptr);
if (size == ubyte .sizeof)
* cast (ubyte * )ptr = 0 ;
else if (size == ushort .sizeof)
* cast (ushort * )ptr = 0 ;
else if (size == uint .sizeof)
* cast (uint * )ptr = 0 ;
else
memset(ptr, 0 , size);
if (typeInfoSize)
* cast (TypeInfo * )(ptr + blkInf.size - typeInfoSize) = ti;
auto blkInf = GC .qalloc(size, flags, ti);
auto p = blkInf.base;
return ptr;
// }
if (tiSize)
* cast ( TypeInfo * )(p + blkInf.size - tiSize) = cast () ti;
return p;
}
extern (C ) void * _d_newitemiT(TypeInfo _ti)
// / Same as above, zero initializes the item.
extern (C ) void * _d_newitemT(in TypeInfo _ti)
{
auto ti = unqualify(_ti);
auto size = ti.tsize; // array element size
auto baseFlags = ! (ti.flags & 1 ) ? BlkAttr.NO_SCAN : 0 ;
size_t typeInfoSize = structTypeInfoSize(ti);
size += typeInfoSize; // Need space for the type info
if (typeInfoSize)
baseFlags |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE ;
debug (PRINTF ) printf(" _d_newitemiT(size = %d)\n " , size);
/* if (length == 0 || size == 0)
result = null;
else
{*/
auto initializer = ti.init();
auto isize = initializer.length;
auto q = initializer.ptr;
auto blkInf = GC .qalloc(size, baseFlags, ti);
auto ptr = blkInf.base;
debug (PRINTF ) printf(" p = %p\n " , ptr);
if (isize == 1 )
* cast (ubyte * )ptr = * cast (ubyte * )q;
else if (isize == ushort .sizeof)
* cast (ushort * )ptr = * cast (ushort * )q;
else if (isize == uint .sizeof)
* cast (uint * )ptr = * cast (uint * )q;
else
memcpy(ptr, q, isize);
auto p = _d_newitemU(_ti);
memset(p, 0 , _ti.tsize);
return p;
}
if (typeInfoSize)
* cast (TypeInfo * )(ptr + blkInf.size - typeInfoSize) = ti;
return ptr;
// }
// / Same as above, for item with non-zero initializer.
extern (C ) void * _d_newitemiT(in TypeInfo _ti)
{
auto p = _d_newitemU(_ti);
auto init = _ti.init();
assert (init.length <= _ti.tsize);
memcpy(p, init.ptr, init.length);
return p;
}
/**
Expand Down
Expand Up
@@ -2116,8 +2077,7 @@ out (result)
// If a postblit is involved, the contents of result might rightly differ
// from the bitwise concatenation of x and y.
auto pb = &tinext.postblit;
if (pb.funcptr is &TypeInfo .postblit)
if (! hasPostblit(tinext))
{
for (size_t i = 0 ; i < x.length * sizeelem; i++ )
assert ((cast (byte * )result)[i] == (cast (byte * )x)[i]);
Expand Down
Expand Up
@@ -2558,9 +2518,9 @@ unittest
}
// associative arrays
import rt.aaA;
import rt.aaA : entryDtor ;
// throw away all existing AA entries with dtor
GC .runFinalizers((cast (char * )(&Entry.Dtor ))[0 .. 1 ]);
GC .runFinalizers((cast (char * )(&entryDtor ))[0 .. 1 ]);
S1 [int ] aa1;
aa1[0 ] = S1 (0 );
Expand All
@@ -2569,7 +2529,7 @@ unittest
{
dtorCount = 0 ;
aa1 = null ;
GC .runFinalizers((cast (char * )(&Entry.Dtor ))[0 .. 1 ]);
GC .runFinalizers((cast (char * )(&entryDtor ))[0 .. 1 ]);
assert (dtorCount == 2 );
}
Expand All
@@ -2581,7 +2541,7 @@ unittest
{
dtorCount = 0 ;
aa2 = null ;
GC .runFinalizers((cast (char * )(&Entry.Dtor ))[0 .. 1 ]);
GC .runFinalizers((cast (char * )(&entryDtor ))[0 .. 1 ]);
assert (dtorCount == 3 );
}
Expand All
@@ -2592,7 +2552,7 @@ unittest
{
dtorCount = 0 ;
aa3 = null ;
GC .runFinalizers((cast (char * )(&Entry.Dtor ))[0 .. 1 ]);
GC .runFinalizers((cast (char * )(&entryDtor ))[0 .. 1 ]);
assert (dtorCount == 4 );
}
}
Expand Down