diff --git a/compiler/src/dmd/dcast.d b/compiler/src/dmd/dcast.d index f29b20458c..172c8278f7 100644 --- a/compiler/src/dmd/dcast.d +++ b/compiler/src/dmd/dcast.d @@ -2832,6 +2832,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) (*ae.keys)[i] = ex; } ae.type = t; + semanticTypeInfo(sc, ae.type); return ae; } return visit(e); diff --git a/compiler/src/dmd/declaration.d b/compiler/src/dmd/declaration.d index 11c4ee75d2..75b898e99e 100644 --- a/compiler/src/dmd/declaration.d +++ b/compiler/src/dmd/declaration.d @@ -1548,6 +1548,8 @@ extern (C++) final class TypeInfoStaticArrayDeclaration : TypeInfoDeclaration */ extern (C++) final class TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration { + Type entry; // type of TypeInfo_AssociativeArray.Entry!(t.index, t.next) + extern (D) this(Type tinfo) { super(tinfo); diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 7e57ed1e99..f3a9809fa1 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -11168,6 +11168,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.e2 = e2x; t1 = e1x.type.toBasetype(); } + else if (t1.ty == Taarray) + { + // when assigning a constant, the need for TypeInfo might change + semanticTypeInfo(sc, t1); + } /* Check the mutability of e1. */ if (auto ale = exp.e1.isArrayLengthExp()) @@ -13307,8 +13312,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (exp.e1.type.toBasetype().ty == Taarray) + { semanticTypeInfo(sc, exp.e1.type.toBasetype()); - + getTypeInfoType(exp.loc, exp.e1.type, sc); + } if (!target.isVectorOpSupported(t1, exp.op, t2)) { @@ -16849,6 +16856,9 @@ void semanticTypeInfo(Scope* sc, Type t) { semanticTypeInfo(sc, t.index); semanticTypeInfo(sc, t.next); + + if (global.params.useTypeInfo) + getTypeInfoType(t.loc, t, sc); } void visitStruct(TypeStruct t) diff --git a/compiler/src/dmd/id.d b/compiler/src/dmd/id.d index 9833e1980e..fa7fe1d5ed 100644 --- a/compiler/src/dmd/id.d +++ b/compiler/src/dmd/id.d @@ -166,6 +166,7 @@ immutable Msgtable[] msgtable = { "xopCmp", "__xopCmp" }, { "xtoHash", "__xtoHash" }, { "__tmpfordtor" }, + { "Entry" }, { "LINE", "__LINE__" }, { "FILE", "__FILE__" }, diff --git a/compiler/src/dmd/semantic2.d b/compiler/src/dmd/semantic2.d index 31fc418dbc..893dc1b9d7 100644 --- a/compiler/src/dmd/semantic2.d +++ b/compiler/src/dmd/semantic2.d @@ -852,6 +852,8 @@ private extern(C++) final class StaticAAVisitor : SemanticTimeTransitiveVisitor loweredExp = loweredExp.ctfeInterpret(); aaExp.lowering = loweredExp; + + semanticTypeInfo(sc, loweredExp.type); } // https://issues.dlang.org/show_bug.cgi?id=24602 diff --git a/compiler/src/dmd/todt.d b/compiler/src/dmd/todt.d index fe57c69eb5..7505b2c83f 100644 --- a/compiler/src/dmd/todt.d +++ b/compiler/src/dmd/todt.d @@ -1348,7 +1348,7 @@ private extern (C++) class TypeInfoDtVisitor : Visitor override void visit(TypeInfoAssociativeArrayDeclaration d) { //printf("TypeInfoAssociativeArrayDeclaration.toDt()\n"); - verifyStructSize(Type.typeinfoassociativearray, 4 * target.ptrsize); + verifyStructSize(Type.typeinfoassociativearray, 5 * target.ptrsize); dtb.xoff(toVtblSymbol(Type.typeinfoassociativearray), 0); // vtbl for TypeInfo_AssociativeArray if (Type.typeinfoassociativearray.hasMonitor()) @@ -1361,6 +1361,9 @@ private extern (C++) class TypeInfoDtVisitor : Visitor TypeInfo_toObjFile(null, d.loc, tc.index); dtb.xoff(toSymbol(tc.index.vtinfo), 0); // TypeInfo for array of type + + TypeInfo_toObjFile(null, d.loc, d.entry); + dtb.xoff(toSymbol(d.entry.vtinfo), 0); // TypeInfo for key,value-pair } override void visit(TypeInfoFunctionDeclaration d) diff --git a/compiler/src/dmd/typesem.d b/compiler/src/dmd/typesem.d index 1c4de00fdc..f274ec536a 100644 --- a/compiler/src/dmd/typesem.d +++ b/compiler/src/dmd/typesem.d @@ -7023,6 +7023,39 @@ Type sharedWildConstOf(Type type) return t; } +Type nakedOf(Type type) +{ + //printf("Type::nakedOf() %p, %s\n", type, type.toChars()); + if (type.mod == 0) + return type; + if (type.mcache) with(type.mcache) + { + // the cache has the naked type at the "identity" position, try to find it + if (cto && cto.mod == 0) + return cto; + if (ito && ito.mod == 0) + return ito; + if (sto && sto.mod == 0) + return sto; + if (scto && scto.mod == 0) + return scto; + if (wto && wto.mod == 0) + return wto; + if (wcto && wcto.mod == 0) + return wcto; + if (swto && swto.mod == 0) + return swto; + if (swcto && swcto.mod == 0) + return swcto; + } + Type t = type.nullAttributes(); + t.mod = 0; + t = t.merge(); + t.fixTo(type); + //printf("\t%p %s\n", t, t.toChars()); + return t; +} + Type unqualify(Type type, uint m) { Type t = type.mutableOf().unSharedOf(); diff --git a/compiler/src/dmd/typinf.d b/compiler/src/dmd/typinf.d index 83fc65cd1e..9554eb3214 100644 --- a/compiler/src/dmd/typinf.d +++ b/compiler/src/dmd/typinf.d @@ -22,6 +22,7 @@ import dmd.expression; import dmd.globals; import dmd.location; import dmd.mtype; +import dmd.typesem; import core.stdc.stdio; /**************************************************** @@ -67,6 +68,9 @@ bool genTypeInfo(Expression e, Loc loc, Type torig, Scope* sc) import dmd.typesem : merge2; Type t = torig.merge2(); // do this since not all Type's are merge'd + if (t.ty == Taarray) + t = makeNakedAssociativeArray(cast(TypeAArray)t); + bool needsCodegen = false; if (!t.vtinfo) { @@ -79,7 +83,7 @@ bool genTypeInfo(Expression e, Loc loc, Type torig, Scope* sc) else if (t.isWild()) t.vtinfo = TypeInfoWildDeclaration.create(t); else - t.vtinfo = getTypeInfoDeclaration(t); + t.vtinfo = getTypeInfoDeclaration(t, sc); assert(t.vtinfo); // ClassInfos are generated as part of ClassDeclaration codegen @@ -115,7 +119,7 @@ extern (C++) Type getTypeInfoType(Loc loc, Type t, Scope* sc) return t.vtinfo.type; } -private TypeInfoDeclaration getTypeInfoDeclaration(Type t) +private TypeInfoDeclaration getTypeInfoDeclaration(Type t, Scope* sc) { //printf("Type::getTypeInfoDeclaration() %s\n", t.toChars()); switch (t.ty) @@ -127,7 +131,7 @@ private TypeInfoDeclaration getTypeInfoDeclaration(Type t) case Tsarray: return TypeInfoStaticArrayDeclaration.create(t); case Taarray: - return TypeInfoAssociativeArrayDeclaration.create(t); + return getTypeInfoAssocArrayDeclaration(cast(TypeAArray)t, sc); case Tstruct: return TypeInfoStructDeclaration.create(t); case Tvector: @@ -151,6 +155,69 @@ private TypeInfoDeclaration getTypeInfoDeclaration(Type t) } } +/****************************************** + * Instantiate TypeInfoAssociativeArrayDeclaration and fill + * the entry with TypeInfo_AssociativeArray.Entry!(t.index, t.next) + * + * Params: + * t = TypeAArray to generate TypeInfo_AssociativeArray for + * sc = context + * Returns: + * a TypeInfoAssociativeArrayDeclaration with field entry initialized + */ +TypeInfoDeclaration getTypeInfoAssocArrayDeclaration(TypeAArray t, Scope* sc) +{ + import dmd.arraytypes; + import dmd.expressionsem; + import dmd.id; + + assert(sc); // must not be called in the code generation phase + + auto ti = TypeInfoAssociativeArrayDeclaration.create(t); + t.vtinfo = ti; // assign it early to avoid recursion in expressionSemantic + Loc loc = t.loc; + auto tiargs = new Objects(); + tiargs.push(t.index); // always called with naked types + tiargs.push(t.next); + + Expression id = new IdentifierExp(loc, Id.empty); + id = new DotIdExp(loc, id, Id.object); + id = new DotIdExp(loc, id, Id.TypeInfo_AssociativeArray); + auto tempinst = new DotTemplateInstanceExp(loc, id, Id.Entry, tiargs); + auto e = expressionSemantic(tempinst, sc); + assert(e.type); + ti.entry = e.type; + if (auto ts = ti.entry.isTypeStruct()) + { + ts.sym.requestTypeInfo = true; + if (auto tmpl = ts.sym.isInstantiated()) + tmpl.minst = sc._module.importedFrom; // ensure it get's emitted + } + getTypeInfoType(loc, ti.entry, sc); + assert(ti.entry.vtinfo); + + return ti; +} + +/****************************************** +* Find or create a TypeAArray with index and next without any modifiers +* +* Params: +* t = TypeAArray to convert +* Returns: +* t = found type +*/ +Type makeNakedAssociativeArray(TypeAArray t) +{ + Type tindex = t.index.toBasetype().nakedOf(); + Type tnext = t.next.toBasetype().nakedOf(); + if (tindex == t.index && tnext == t.next) + return t; + + t = new TypeAArray(tnext, tindex); + return t.merge(); +} + /************************************************** * Returns: * true if any part of type t is speculative. diff --git a/druntime/src/core/internal/newaa.d b/druntime/src/core/internal/newaa.d index 7c858f3352..19a33160eb 100644 --- a/druntime/src/core/internal/newaa.d +++ b/druntime/src/core/internal/newaa.d @@ -44,7 +44,7 @@ struct Impl Bucket[] buckets; uint used; uint deleted; - TypeInfo_Struct entryTI; + const(TypeInfo) entryTI; uint firstUsed; immutable uint keysz; immutable uint valsz; diff --git a/druntime/src/object.d b/druntime/src/object.d index d8389ae491..e274fd30e8 100644 --- a/druntime/src/object.d +++ b/druntime/src/object.d @@ -1324,8 +1324,16 @@ class TypeInfo_AssociativeArray : TypeInfo override @property inout(TypeInfo) next() nothrow pure inout { return value; } override @property uint flags() nothrow pure const { return 1; } + // TypeInfo entry is generated from the type of this template to help rt/aaA.d + static struct Entry(K, V) + { + K key; + V value; + } + TypeInfo value; TypeInfo key; + TypeInfo entry; override @property size_t talign() nothrow pure const { diff --git a/druntime/src/rt/aaA.d b/druntime/src/rt/aaA.d index 2bddeaf41d..3b4bee0405 100644 --- a/druntime/src/rt/aaA.d +++ b/druntime/src/rt/aaA.d @@ -66,13 +66,13 @@ private: if ((ti.key.flags | ti.value.flags) & 1) flags |= Flags.hasPointers; - entryTI = fakeEntryTI(this, ti.key, ti.value); + entryTI = ti.entry; } Bucket[] buckets; uint used; uint deleted; - TypeInfo_Struct entryTI; + const(TypeInfo) entryTI; uint firstUsed; immutable uint keysz; immutable uint valsz; @@ -229,15 +229,6 @@ private void* allocEntry(scope const Impl* aa, scope const void* pkey) return res; } -package void entryDtor(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); - extra[1].destroy(p + talign(extra[0].tsize, extra[1].talign)); -} - private bool hasDtor(const TypeInfo ti) pure nothrow { import rt.lifetime : unqualify; @@ -258,132 +249,6 @@ private immutable(void)* getRTInfo(const TypeInfo ti) pure nothrow return isNoClass ? ti.rtInfo() : rtinfoHasPointers; } -// build type info for Entry with additional key and value fields -TypeInfo_Struct fakeEntryTI(ref Impl aa, const TypeInfo keyti, const TypeInfo valti) nothrow -{ - import rt.lifetime : unqualify; - - auto kti = unqualify(keyti); - auto vti = unqualify(valti); - - // figure out whether RTInfo has to be generated (indicated by rtisize > 0) - enum pointersPerWord = 8 * (void*).sizeof * (void*).sizeof; - auto rtinfo = rtinfoNoPointers; - size_t rtisize = 0; - immutable(size_t)* keyinfo = void; - immutable(size_t)* valinfo = void; - if (aa.flags & Impl.Flags.hasPointers) - { - // classes are references - keyinfo = cast(immutable(size_t)*) getRTInfo(keyti); - valinfo = cast(immutable(size_t)*) getRTInfo(valti); - - if (keyinfo is rtinfoHasPointers && valinfo is rtinfoHasPointers) - rtinfo = rtinfoHasPointers; - else - rtisize = 1 + (aa.valoff + aa.valsz + pointersPerWord - 1) / pointersPerWord; - } - bool entryHasDtor = hasDtor(kti) || hasDtor(vti); - if (rtisize == 0 && !entryHasDtor) - return null; - - // save kti and vti after type info for struct - enum sizeti = __traits(classInstanceSize, TypeInfo_Struct); - void* p = GC.malloc(sizeti + (2 + rtisize) * (void*).sizeof); - import core.stdc.string : memcpy; - - memcpy(p, __traits(initSymbol, TypeInfo_Struct).ptr, sizeti); - - auto ti = cast(TypeInfo_Struct) p; - auto extra = cast(TypeInfo*)(p + sizeti); - extra[0] = cast() kti; - extra[1] = cast() vti; - - static immutable tiMangledName = "S2rt3aaA__T5EntryZ"; - ti.mangledName = tiMangledName; - - ti.m_RTInfo = rtisize > 0 ? rtinfoEntry(aa, keyinfo, valinfo, cast(size_t*)(extra + 2), rtisize) : rtinfo; - ti.m_flags = ti.m_RTInfo is rtinfoNoPointers ? cast(TypeInfo_Struct.StructFlags)0 : TypeInfo_Struct.StructFlags.hasPointers; - - // 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 - immutable entrySize = aa.valoff + aa.valsz; - ti.m_init = (cast(ubyte*) null)[0 .. entrySize]; // init length, but not ptr - - if (entryHasDtor) - { - // xdtor needs to be built from the dtors of key and value for the GC - ti.xdtorti = &entryDtor; - ti.m_flags |= TypeInfo_Struct.StructFlags.isDynamicType; - } - - ti.m_align = cast(uint) max(kti.talign, vti.talign); - - return ti; -} - -// build appropriate RTInfo at runtime -immutable(void)* rtinfoEntry(ref Impl aa, immutable(size_t)* keyinfo, - immutable(size_t)* valinfo, size_t* rtinfoData, size_t rtinfoSize) pure nothrow -{ - enum bitsPerWord = 8 * size_t.sizeof; - - rtinfoData[0] = aa.valoff + aa.valsz; - rtinfoData[1..rtinfoSize] = 0; - - void copyKeyInfo(string src)() - { - size_t pos = 1; - size_t keybits = aa.keysz / (void*).sizeof; - while (keybits >= bitsPerWord) - { - rtinfoData[pos] = mixin(src); - keybits -= bitsPerWord; - pos++; - } - if (keybits > 0) - rtinfoData[pos] = mixin(src) & ((size_t(1) << keybits) - 1); - } - - if (keyinfo is rtinfoHasPointers) - copyKeyInfo!"~size_t(0)"(); - else if (keyinfo !is rtinfoNoPointers) - copyKeyInfo!"keyinfo[pos]"(); - - void copyValInfo(string src)() - { - size_t bitpos = aa.valoff / (void*).sizeof; - size_t pos = 1; - size_t dstpos = 1 + bitpos / bitsPerWord; - size_t begoff = bitpos % bitsPerWord; - size_t valbits = aa.valsz / (void*).sizeof; - size_t endoff = (bitpos + valbits) % bitsPerWord; - for (;;) - { - const bits = bitsPerWord - begoff; - size_t s = mixin(src); - rtinfoData[dstpos] |= s << begoff; - if (begoff > 0 && valbits > bits) - rtinfoData[dstpos+1] |= s >> bits; - if (valbits < bitsPerWord) - break; - valbits -= bitsPerWord; - dstpos++; - pos++; - } - if (endoff > 0) - rtinfoData[dstpos] &= (size_t(1) << endoff) - 1; - } - - if (valinfo is rtinfoHasPointers) - copyValInfo!"~size_t(0)"(); - else if (valinfo !is rtinfoNoPointers) - copyValInfo!"valinfo[pos]"(); - - return cast(immutable(void)*) rtinfoData; -} - unittest { void test(K, V)() @@ -402,12 +267,10 @@ unittest if (valrti is rtinfoNoPointers && keyrti is rtinfoNoPointers) { assert(!(impl.flags & Impl.Flags.hasPointers)); - assert(impl.entryTI is null); } else if (valrti is rtinfoHasPointers && keyrti is rtinfoHasPointers) { assert(impl.flags & Impl.Flags.hasPointers); - assert(impl.entryTI is null); } else { @@ -977,7 +840,10 @@ unittest aa1 = null; aa2 = null; aa3 = null; - GC.runFinalizers((cast(char*)&entryDtor)[0 .. 1]); + auto dtor1 = typeid(TypeInfo_AssociativeArray.Entry!(int, T)).xdtor; + GC.runFinalizers((cast(char*)dtor1)[0 .. 1]); + auto dtor2 = typeid(TypeInfo_AssociativeArray.Entry!(T, int)).xdtor; + GC.runFinalizers((cast(char*)dtor2)[0 .. 1]); assert(T.dtor == 6 && T.postblit == 2); } diff --git a/druntime/src/rt/lifetime.d b/druntime/src/rt/lifetime.d index b63a5bf526..f77d8b9c4e 100644 --- a/druntime/src/rt/lifetime.d +++ b/druntime/src/rt/lifetime.d @@ -1587,16 +1587,13 @@ deprecated unittest GC.free(blkinf.base); // associative arrays - import rt.aaA : entryDtor; - // throw away all existing AA entries with dtor - GC.runFinalizers((cast(char*)&entryDtor)[0..1]); - S1[int] aa1; aa1[0] = S1(0); aa1[1] = S1(1); dtorCount = 0; aa1 = null; - GC.runFinalizers((cast(char*)&entryDtor)[0..1]); + auto dtor1 = typeid(TypeInfo_AssociativeArray.Entry!(int, S1)).xdtor; + GC.runFinalizers((cast(char*)dtor1)[0..1]); assert(dtorCount == 2); int[S1] aa2; @@ -1605,7 +1602,8 @@ deprecated unittest aa2[S1(2)] = 2; dtorCount = 0; aa2 = null; - GC.runFinalizers((cast(char*)&entryDtor)[0..1]); + auto dtor2 = typeid(TypeInfo_AssociativeArray.Entry!(S1, int)).xdtor; + GC.runFinalizers((cast(char*)dtor2)[0..1]); assert(dtorCount == 3); S1[2][int] aa3; @@ -1613,7 +1611,8 @@ deprecated unittest aa3[1] = [S1(1),S1(3)]; dtorCount = 0; aa3 = null; - GC.runFinalizers((cast(char*)&entryDtor)[0..1]); + auto dtor3 = typeid(TypeInfo_AssociativeArray.Entry!(int, S1[2])).xdtor; + GC.runFinalizers((cast(char*)dtor3)[0..1]); assert(dtorCount == 4); } diff --git a/druntime/test/profile/myprofilegc.log.freebsd.32.exp b/druntime/test/profile/myprofilegc.log.freebsd.32.exp index cddce901b6..0053d15aaa 100644 --- a/druntime/test/profile/myprofilegc.log.freebsd.32.exp +++ b/druntime/test/profile/myprofilegc.log.freebsd.32.exp @@ -1,5 +1,5 @@ bytes allocated, allocations, type, function, file:line - 256 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 + 160 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 128 1 float profilegc.main src/profilegc.d:18 128 1 int profilegc.main src/profilegc.d:15 64 1 double[] profilegc.main src/profilegc.d:56 diff --git a/druntime/test/profile/myprofilegc.log.freebsd.64.exp b/druntime/test/profile/myprofilegc.log.freebsd.64.exp index 8bc03494d7..97c1aaa253 100644 --- a/druntime/test/profile/myprofilegc.log.freebsd.64.exp +++ b/druntime/test/profile/myprofilegc.log.freebsd.64.exp @@ -1,5 +1,5 @@ bytes allocated, allocations, type, function, file:line - 496 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 + 320 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 160 1 float profilegc.main src/profilegc.d:18 160 1 int profilegc.main src/profilegc.d:15 64 1 double[] profilegc.main src/profilegc.d:56 diff --git a/druntime/test/profile/myprofilegc.log.linux.32.exp b/druntime/test/profile/myprofilegc.log.linux.32.exp index 895feb3932..2dc8e5ccf3 100644 --- a/druntime/test/profile/myprofilegc.log.linux.32.exp +++ b/druntime/test/profile/myprofilegc.log.linux.32.exp @@ -1,5 +1,5 @@ bytes allocated, allocations, type, function, file:line - 256 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 + 160 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 128 1 float profilegc.main src/profilegc.d:18 128 1 int profilegc.main src/profilegc.d:15 64 1 double[] profilegc.main src/profilegc.d:56 diff --git a/druntime/test/profile/myprofilegc.log.linux.64.exp b/druntime/test/profile/myprofilegc.log.linux.64.exp index 8bc03494d7..97c1aaa253 100644 --- a/druntime/test/profile/myprofilegc.log.linux.64.exp +++ b/druntime/test/profile/myprofilegc.log.linux.64.exp @@ -1,5 +1,5 @@ bytes allocated, allocations, type, function, file:line - 496 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 + 320 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 160 1 float profilegc.main src/profilegc.d:18 160 1 int profilegc.main src/profilegc.d:15 64 1 double[] profilegc.main src/profilegc.d:56 diff --git a/druntime/test/profile/myprofilegc.log.osx.32.exp b/druntime/test/profile/myprofilegc.log.osx.32.exp index 564f8e03a3..1cea04eced 100644 --- a/druntime/test/profile/myprofilegc.log.osx.32.exp +++ b/druntime/test/profile/myprofilegc.log.osx.32.exp @@ -1,5 +1,5 @@ bytes allocated, allocations, type, function, file:line - 176 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 + 160 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 128 1 float profilegc.main src/profilegc.d:18 128 1 int profilegc.main src/profilegc.d:15 64 1 float[] profilegc.main src/profilegc.d:42 diff --git a/druntime/test/profile/myprofilegc.log.osx.64.exp b/druntime/test/profile/myprofilegc.log.osx.64.exp index 8bc03494d7..97c1aaa253 100644 --- a/druntime/test/profile/myprofilegc.log.osx.64.exp +++ b/druntime/test/profile/myprofilegc.log.osx.64.exp @@ -1,5 +1,5 @@ bytes allocated, allocations, type, function, file:line - 496 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 + 320 1 immutable(char)[][int] profilegc.main src/profilegc.d:23 160 1 float profilegc.main src/profilegc.d:18 160 1 int profilegc.main src/profilegc.d:15 64 1 double[] profilegc.main src/profilegc.d:56 diff --git a/druntime/test/profile/myprofilegc.log.windows.32.exp b/druntime/test/profile/myprofilegc.log.windows.32.exp index cdb4b8c068..cf29c52048 100644 --- a/druntime/test/profile/myprofilegc.log.windows.32.exp +++ b/druntime/test/profile/myprofilegc.log.windows.32.exp @@ -1,5 +1,5 @@ bytes allocated, allocations, type, function, file:line - 256 1 immutable(char)[][int] profilegc.main src\profilegc.d:23 + 160 1 immutable(char)[][int] profilegc.main src\profilegc.d:23 128 1 float profilegc.main src\profilegc.d:18 128 1 int profilegc.main src\profilegc.d:15 64 1 double[] profilegc.main src\profilegc.d:56 diff --git a/druntime/test/profile/myprofilegc.log.windows.64.exp b/druntime/test/profile/myprofilegc.log.windows.64.exp index 38cd4d3773..631c404941 100644 --- a/druntime/test/profile/myprofilegc.log.windows.64.exp +++ b/druntime/test/profile/myprofilegc.log.windows.64.exp @@ -1,5 +1,5 @@ bytes allocated, allocations, type, function, file:line - 496 1 immutable(char)[][int] profilegc.main src\profilegc.d:23 + 320 1 immutable(char)[][int] profilegc.main src\profilegc.d:23 160 1 float profilegc.main src\profilegc.d:18 160 1 int profilegc.main src\profilegc.d:15 64 1 double[] profilegc.main src\profilegc.d:56