Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions src/object.di
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ class TypeInfo_Class : TypeInfo
void* deallocator;
OffsetTypeInfo[] m_offTi;
void* defaultConstructor;
immutable(void)* m_rtInfo; // data for precise GC
immutable(void)* m_RTInfo; // data for precise GC

static const(TypeInfo_Class) find(in char[] classname);
Object create() const;
Expand Down Expand Up @@ -234,11 +234,16 @@ class TypeInfo_Struct : TypeInfo
enum StructFlags : uint
{
hasPointers = 0x1,
isDynamicType = 0x2, // built at runtime, needs type info in xdtor
}
StructFlags m_flags;
}
void function(void*) xdtor;
void function(void*) xpostblit;
union
{
void function(void*) xdtor;
void function(void*, const TypeInfo_Struct ti) xdtorti;
}
void function(void*) xpostblit;

uint m_align;

Expand All @@ -247,7 +252,7 @@ class TypeInfo_Struct : TypeInfo
TypeInfo m_arg1;
TypeInfo m_arg2;
}
immutable(void)* m_rtInfo;
immutable(void)* m_RTInfo;
}

class TypeInfo_Tuple : TypeInfo
Expand Down Expand Up @@ -394,7 +399,7 @@ extern (C)
// from druntime/src/rt/aaA.d

// size_t _aaLen(in void* p) pure nothrow @nogc;
private void* _aaGetX(void** paa, const TypeInfo keyti, in size_t valuesize, in void* pkey) pure nothrow;
private void* _aaGetY(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey) pure nothrow;
// inout(void)* _aaGetRvalueX(inout void* p, in TypeInfo keyti, in size_t valuesize, in void* pkey);
inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize, const TypeInfo tiValArray) pure nothrow;
inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow;
Expand Down Expand Up @@ -468,7 +473,7 @@ V[K] dup(T : V[K], K, V)(T aa)
{
import core.stdc.string : memcpy;

void* pv = _aaGetX(cast(void**)&result, typeid(K), V.sizeof, &k);
void* pv = _aaGetY(cast(void**)&result, typeid(V[K]), V.sizeof, &k);
memcpy(pv, &v, V.sizeof);
return *cast(V*)pv;
}
Expand Down
18 changes: 13 additions & 5 deletions src/object_.d
Original file line number Diff line number Diff line change
Expand Up @@ -1054,11 +1054,14 @@ class TypeInfo_Struct : TypeInfo

override @property size_t talign() nothrow pure const { return m_align; }

override void destroy(void* p) const
final override void destroy(void* p) const
{
if (xdtor)
{
(*xdtor)(p);
if (m_flags & StructFlags.isDynamicType)
(*xdtorti)(p, this);
else
(*xdtor)(p);
}
}

Expand All @@ -1081,10 +1084,15 @@ class TypeInfo_Struct : TypeInfo
enum StructFlags : uint
{
hasPointers = 0x1,
isDynamicType = 0x2, // built at runtime, needs type info in xdtor
}
StructFlags m_flags;
}
void function(void*) xdtor;
union
{
void function(void*) xdtor;
void function(void*, const TypeInfo_Struct ti) xdtorti;
}
void function(void*) xpostblit;

uint m_align;
Expand Down Expand Up @@ -1983,7 +1991,7 @@ extern (C)
// from druntime/src/rt/aaA.d

// size_t _aaLen(in void* p) pure nothrow @nogc;
private void* _aaGetX(void** paa, const TypeInfo keyti, in size_t valuesize, in void* pkey) pure nothrow;
private void* _aaGetY(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey) pure nothrow;
// inout(void)* _aaGetRvalueX(inout void* p, in TypeInfo keyti, in size_t valuesize, in void* pkey);
inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize, const TypeInfo tiValArray) pure nothrow;
inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow;
Expand Down Expand Up @@ -2062,7 +2070,7 @@ V[K] dup(T : V[K], K, V)(T aa)
{
import core.stdc.string : memcpy;

void* pv = _aaGetX(cast(void**)&result, typeid(K), V.sizeof, &k);
void* pv = _aaGetY(cast(void**)&result, typeid(V[K]), V.sizeof, &k);
memcpy(pv, &v, V.sizeof);
return *cast(V*)pv;
}
Expand Down
125 changes: 89 additions & 36 deletions src/rt/aaA.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private
import core.stdc.string;
import core.stdc.stdio;
import core.memory;
import rt.lifetime : _d_newarrayU;
import rt.lifetime : _d_newarrayU, _d_newitemT, unqualify, __doPostblit;

// Convenience function to make sure the NO_INTERIOR gets set on the
// bucket array.
Expand Down Expand Up @@ -64,14 +64,82 @@ struct Entry
size_t hash;
/* key */
/* value */

static void Dtor(void*p, const TypeInfo_Struct sti)
{
// key and value type info stored after the TypeInfo_Struct by tiEntry()
auto sizeti = __traits(classInstanceSize, TypeInfo_Struct);
auto extra = cast(const(TypeInfo)*) (cast(void*)sti + sizeti);
extra[0].destroy(p + Entry.sizeof);
extra[1].destroy(p + Entry.sizeof + aligntsize(extra[0].tsize));
}
}

private bool hasDtor(const TypeInfo ti)
{
if (!ti)
return false;
if (typeid(ti) is typeid(TypeInfo_Struct))
if ((cast(TypeInfo_Struct)cast(void*)ti).xdtor)
return true;
if (typeid(ti) is typeid(TypeInfo_StaticArray))
return hasDtor(unqualify(ti.next()));

return false;
}

// build type info for Entry with additional key and value fields
TypeInfo_Struct tiEntry(const TypeInfo keyti, const TypeInfo valti)
{
auto kti = unqualify(keyti);
auto vti = unqualify(valti);
if (!hasDtor(kti) && !hasDtor(vti))
return null;

// save kti and vti after type info for struct
auto sizeti = __traits(classInstanceSize, TypeInfo_Struct);
auto sizeall = sizeti + 2 * (void*).sizeof;
void* p = GC.malloc(sizeall);
memcpy(p, typeid(TypeInfo_Struct).init().ptr, sizeti);

auto ti = cast(TypeInfo_Struct)p;
auto extra = cast(TypeInfo*) (p + sizeti);
extra[0] = cast() kti;
extra[1] = cast() vti;

static immutable tiName = __MODULE__ ~ ".Entry!(...)";
ti.name = tiName;

// we don't expect the Entry objects to be used outside of this module, so we have control
// over the non-usage of the callback methods and other entries and can keep these null
// xtoHash, xopEquals, xopCmp, xtoString and xpostblit
ti.m_RTInfo = null;
auto sizeEntry = Entry.sizeof + aligntsize(kti.tsize()) + valti.tsize();
ti.m_init = (cast(char*)null)[0..sizeEntry]; // init length, but not ptr

// xdtor needs to be built from the dtors of key and value for the GC
ti.xdtorti = &Entry.Dtor;

ti.m_flags = TypeInfo_Struct.StructFlags.hasPointers | TypeInfo_Struct.StructFlags.isDynamicType;
ti.m_align = cast(uint) aligntsize(1);

return ti;
}

struct Impl
{
this(const TypeInfo_AssociativeArray ti)
{
_keyti = cast() ti.key;
_entryti = cast() tiEntry(_keyti, ti.next);
}

Entry*[] buckets;
size_t nodes; // total number of entries
size_t firstUsedBucket; // starting index for first used bucket.
TypeInfo _keyti;
TypeInfo _keyti; // these should be const, but missing tail const for classes make this ugly
TypeInfo_Struct _entryti;

Entry*[4] binit; // initial value of buckets[]

@property const(TypeInfo) keyti() const @safe pure nothrow @nogc
Expand Down Expand Up @@ -160,31 +228,13 @@ body
* Get pointer to value in associative array indexed by key.
* Add entry for key if it is not already there.
*/
void* _aaGetX(AA* aa, const TypeInfo keyti, in size_t valuesize, in void* pkey)
in
{
assert(aa);
}
body
{
if (aa.impl is null)
{
aa.impl = new Impl();
aa.impl.buckets = aa.impl.binit[];
aa.impl.firstUsedBucket = aa.impl.buckets.length;
aa.impl._keyti = cast() keyti;
}
return _aaGetImpl(aa, keyti, valuesize, pkey);
}

void* _aaGetY(AA* aa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey)
{
if (aa.impl is null)
{
aa.impl = new Impl();
aa.impl = new Impl(ti);
aa.impl.buckets = aa.impl.binit[];
aa.impl.firstUsedBucket = aa.impl.buckets.length;
aa.impl._keyti = cast() ti.key;
}
return _aaGetImpl(aa, ti.key, valuesize, pkey);
}
Expand All @@ -202,13 +252,6 @@ body
//printf("keyti = %p\n", keyti);
//printf("aa = %p\n", aa);

if (aa.impl is null)
{
aa.impl = new Impl();
aa.impl.buckets = aa.impl.binit[];
aa.impl.firstUsedBucket = aa.impl.buckets.length;
aa.impl._keyti = cast() keyti;
}
//printf("aa = %p\n", aa);
//printf("aa.a = %p\n", aa.a);

Expand All @@ -234,11 +277,15 @@ body
// Not found, create new elem
//printf("create new one\n");
size_t size = Entry.sizeof + aligntsize(keytitsize) + valuesize;
e = cast(Entry *) GC.malloc(size, 0); // TODO: needs typeid(Entry+)
if (aa.impl._entryti)
e = cast(Entry *) _d_newitemT(aa.impl._entryti);
else
e = cast(Entry *) GC.malloc(size, 0); // TODO: needs typeid(Entry+)
e.next = null;
e.hash = key_hash;
ubyte* ptail = cast(ubyte*)(e + 1);
memcpy(ptail, pkey, keytitsize);
__doPostblit(ptail, keytitsize, unqualify(keyti));
memset(ptail + aligntsize(keytitsize), 0, valuesize); // zero value
*pe = e;

Expand All @@ -264,7 +311,8 @@ Lret:
void* _aaGetZ(AA* aa, const TypeInfo keyti, in size_t valuesize, in void* pkey,
void *function(void[], void[]) @trusted pure aaLiteral)
{
return _aaGetX(aa, keyti, valuesize, pkey);
assert(false, "_aaGetZ not implemented");
//return _aaGetX(aa, keyti, valuesize, pkey);
}

// bug 13748
Expand Down Expand Up @@ -356,7 +404,7 @@ bool _aaDelX(AA aa, in TypeInfo keyti, in void* pkey)
if (!(--aa.impl.nodes))
// reset cache, we know there are no nodes in the aa.
aa.impl.firstUsedBucket = aa.impl.buckets.length;
// ee could be freed here, but user code may
// ee could be freed here, but user code may
// hold pointers to it
return true;
}
Expand Down Expand Up @@ -386,12 +434,13 @@ inout(ArrayRet_t) _aaValues(inout AA aa, in size_t keysize, in size_t valuesize,
memcpy(a.ptr + resi * valuesize,
cast(byte*)e + Entry.sizeof + alignsize,
valuesize);
// TODO: no postblit here?
resi++;
e = e.next;
}
}
assert(resi == a.length);
// cannot postblit, it might not be pure
//__doPostblit(a.ptr, alignsize, unqualify(tiValueArray.next));
}
return *cast(inout ArrayRet_t*)(&a);
}
Expand Down Expand Up @@ -450,6 +499,7 @@ body

newImpl.nodes = oldImpl.nodes;
newImpl._keyti = oldImpl._keyti;
newImpl._entryti = oldImpl._entryti;

*paa.impl = newImpl;
}
Expand Down Expand Up @@ -482,12 +532,13 @@ inout(ArrayRet_t) _aaKeys(inout AA aa, in size_t keysize, const TypeInfo tiKeyAr
while (e)
{
memcpy(&res[resi * keysize], cast(byte*)(e + 1), keysize);
// TODO: no postblit here?
resi++;
e = e.next;
}
}
assert(resi == len);
// cannot postblit, it might not be pure
//__doPostblit(res, len * kisize, unqualify(tiKeyArray.next));

Array a;
a.length = len;
Expand Down Expand Up @@ -629,8 +680,7 @@ Impl* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys, vo
}
else
{
result = new Impl();
result._keyti = cast() keyti;
result = new Impl(ti);

size_t i;
for (i = 0; i < prime_list.length - 1; i++)
Expand Down Expand Up @@ -662,7 +712,10 @@ Impl* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys, vo
{
// Not found, create new elem
//printf("create new one\n");
e = cast(Entry *) GC.malloc(Entry.sizeof + keytsize + valuesize); // TODO: needs typeid(Entry+)
if (result._entryti)
e = cast(Entry *) _d_newitemT(result._entryti);
else
e = cast(Entry *) GC.malloc(Entry.sizeof + keytsize + valuesize); // TODO: needs typeid(Entry+)
memcpy(e + 1, pkey, keysize);
e.next = null;
e.hash = key_hash;
Expand Down
Loading