From 33b1ea3657bdf1ccd14039197efc99c543fa9eab Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Sat, 9 Mar 2019 01:50:53 +0200 Subject: [PATCH 1/2] Lower newExp --- src/object.d | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/object.d b/src/object.d index 4bbfe3bc1f..50d24a0bb6 100644 --- a/src/object.d +++ b/src/object.d @@ -38,6 +38,68 @@ alias dstring = immutable(dchar)[]; version (D_ObjectiveC) public import core.attribute : selector; +// Size used to store the TypeInfo at the end of an allocation for structs that +// have a destructor +private size_t structTypeInfoSize(T)() pure nothrow @nogc +{ + // can't use because it's in rt.lifetime + //if (!callStructDtorsDuringGC) + //return 0; + + static if (is(T == struct) && is(typeof({ T t; t.__xdtor; }))) + return size_t.sizeof; + return 0; +} + +/* + * Allocate an uninitialized non-array item. + * This is an optimization to avoid things needed for arrays like the __arrayPad(size). + */ +private T* ___d_newitemU(T)() +{ + import core.memory; + import core.internal.traits : Unqual; + + auto ti = typeid(Unqual!T); + auto flags = !(ti.flags & 1) ? GC.BlkAttr.NO_SCAN : 0; + enum tiSize = structTypeInfoSize!T(); + enum size = T.sizeof + tiSize; + + static if (is(T == struct)) + { + if (tiSize) + flags |= GC.BlkAttr.STRUCTFINAL | GC.BlkAttr.FINALIZE; + } + auto blkInf = GC.qalloc(size, flags, ti); + auto p = blkInf.base; + + static if (is(T == struct)) + { + if (tiSize) + *cast(TypeInfo*)(p + blkInf.size - tiSize) = cast() ti; + } + return cast(T*) p; +} + +// Same as above, for item with non-zero initializer. +T* ___d_newitemT(T)() +{ + import core.stdc.string; + auto p = ___d_newitemU!T(); + memset(p, 0, T.sizeof); + return p; +} + +// Same as above, for item with non-zero initializer. +T* ___d_newitemiT(T)() +{ + import core.stdc.string; + auto p = ___d_newitemU!T(); + auto init = T.init; + memcpy(p, &init, T.sizeof); + return p; +} + int __cmp(T)(scope const T[] lhs, scope const T[] rhs) @trusted if (__traits(isScalar, T)) { From 4cabd7c68f50c76376a5b86fe74bdf7a763c5b01 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 11 Mar 2019 16:45:01 +0200 Subject: [PATCH 2/2] Use T to check if isZeroInitialized --- src/object.d | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/object.d b/src/object.d index 50d24a0bb6..ac86f6aedb 100644 --- a/src/object.d +++ b/src/object.d @@ -85,18 +85,17 @@ private T* ___d_newitemU(T)() T* ___d_newitemT(T)() { import core.stdc.string; - auto p = ___d_newitemU!T(); - memset(p, 0, T.sizeof); - return p; -} - -// Same as above, for item with non-zero initializer. -T* ___d_newitemiT(T)() -{ - import core.stdc.string; - auto p = ___d_newitemU!T(); - auto init = T.init; - memcpy(p, &init, T.sizeof); + import core.internal.traits : Unqual; + auto p = (() @trusted => ___d_newitemU!T())(); + static if (__traits(isZeroInit, T)) + { + () @trusted { memset(cast(Unqual!T *) p, 0, T.sizeof); }(); + } + else + { + auto init = T.init; + () @trusted { memcpy(cast(Unqual!T *) p, &init, T.sizeof); }(); + } return p; }