diff --git a/src/core/internal/array/appending.d b/src/core/internal/array/appending.d index 9f5a1cb68c..5d4f3b498f 100644 --- a/src/core/internal/array/appending.d +++ b/src/core/internal/array/appending.d @@ -104,6 +104,22 @@ ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @ return x; } +/** + * TraceGC wrapper around $(REF _d_arrayappendT, core,internal,array,appending). + */ +ref Tarr _d_arrayappendTTrace(Tarr : T[], T)(string file, int line, string funcname, return ref scope Tarr x, scope Tarr y) @trusted +{ + version (D_TypeInfo) + { + import core.internal.array.utils: TraceHook, gcStatsPure, accumulatePure; + mixin(TraceHook!(Tarr.stringof, "_d_arrayappendT")); + + return _d_arrayappendT(x, y); + } + else + assert(0, "Cannot append to array if compiling without support for runtime type information!"); +} + @safe unittest { double[] arr1; diff --git a/src/core/internal/array/utils.d b/src/core/internal/array/utils.d index 7a829a0b3f..41aa57faf0 100644 --- a/src/core/internal/array/utils.d +++ b/src/core/internal/array/utils.d @@ -11,7 +11,7 @@ module core.internal.array.utils; import core.internal.traits : Parameters; -private auto gcStatsPure() nothrow pure +auto gcStatsPure() nothrow pure { import core.memory : GC; @@ -19,7 +19,7 @@ private auto gcStatsPure() nothrow pure return impureBypass(); } -private ulong accumulatePure(string file, int line, string funcname, string name, ulong size) nothrow pure +ulong accumulatePure(string file, int line, string funcname, string name, ulong size) nothrow pure { static ulong impureBypass(string file, int line, string funcname, string name, ulong size) @nogc nothrow { @@ -35,41 +35,32 @@ private ulong accumulatePure(string file, int line, string funcname, string name } /** - * TraceGC wrapper around runtime hook `Hook`. + * TraceGC wrapper generator around the runtime hook `Hook`. * Params: - * T = Type of hook to report to accumulate - * Hook = The hook to wrap - * errorMessage = The error message incase `version != D_TypeInfo` - * file = File that called `_d_HookTraceImpl` - * line = Line inside of `file` that called `_d_HookTraceImpl` - * funcname = Function that called `_d_HookTraceImpl` - * parameters = Parameters that will be used to call `Hook` - * Bugs: - * This function template needs be between the compiler and a much older runtime hook that bypassed safety, - * purity, and throwabilty checks. To prevent breaking existing code, this function template - * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations. -*/ -auto _d_HookTraceImpl(T, alias Hook, string errorMessage)(string file, int line, string funcname, Parameters!Hook parameters) @trusted pure + * Type = The type of hook to report to accumulate + * Hook = The name hook to wrap + */ +template TraceHook(string Type, string Hook) { - version (D_TypeInfo) - { + const char[] TraceHook = q{ + import core.internal.array.utils : gcStatsPure, accumulatePure; + pragma(inline, false); - string name = T.stringof; + string name = } ~ "`" ~ Type ~ "`;" ~ q{ // FIXME: use rt.tracegc.accumulator when it is accessable in the future. version (tracegc) - { + } ~ "{\n" ~ q{ import core.stdc.stdio; printf("%sTrace file = '%.*s' line = %d function = '%.*s' type = %.*s\n", - Hook.stringof.ptr, + } ~ "\"" ~ Hook ~ "\".ptr," ~ q{ file.length, file.ptr, line, funcname.length, funcname.ptr, name.length, name.ptr ); - } - + } ~ "}\n" ~ q{ ulong currentlyAllocated = gcStatsPure().allocatedInCurrentThread; scope(exit) @@ -86,6 +77,29 @@ auto _d_HookTraceImpl(T, alias Hook, string errorMessage)(string file, int line, assert(0); } } + }; +} + +/** + * TraceGC wrapper around runtime hook `Hook`. + * Params: + * T = Type of hook to report to accumulate + * Hook = The hook to wrap + * errorMessage = The error message incase `version != D_TypeInfo` + * file = File that called `_d_HookTraceImpl` + * line = Line inside of `file` that called `_d_HookTraceImpl` + * funcname = Function that called `_d_HookTraceImpl` + * parameters = Parameters that will be used to call `Hook` + * Bugs: + * This function template needs be between the compiler and a much older runtime hook that bypassed safety, + * purity, and throwabilty checks. To prevent breaking existing code, this function template + * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations. +*/ +auto _d_HookTraceImpl(T, alias Hook, string errorMessage)(string file, int line, string funcname, Parameters!Hook parameters) @trusted pure +{ + version (D_TypeInfo) + { + mixin(TraceHook!(T.stringof, __traits(identifier, Hook))); return Hook(parameters); } else diff --git a/src/object.d b/src/object.d index 02a2a81cae..3a88552f30 100644 --- a/src/object.d +++ b/src/object.d @@ -4883,6 +4883,7 @@ they are only intended to be instantiated by the compiler, not the user. public import core.internal.entrypoint : _d_cmain; public import core.internal.array.appending : _d_arrayappendT; +public import core.internal.array.appending : _d_arrayappendTTrace; public import core.internal.array.appending : _d_arrayappendcTXImpl; public import core.internal.array.comparison : __cmp; public import core.internal.array.equality : __equals;