5eb9927aae
D front-end changes:
- Import dmd v2.100.0.
- Add bit fields to D, enabled via the -fpreview=bitfields switch.
- Removed the -ftransition=markdown and -frevert=markdown switches.
- Added new trait `__traits(classInstanceAlignment)' to provide the
required data alignment for classes.
- The check for `pragma(crt_constructor)' and `pragma(crt_destructor)'
linkage has been relaxed to allow all `void()' signatures.
- ImportC parser now recognizes the `typeof(...)' operator.
D runtime changes:
- Import druntime v2.100.0.
Phobos changes:
- Import phobos v2.100.0.
- To comply with dip1000, `std.socket.Socket` methods now accept only
`scope' arrays.
- The `fill', `alignSize', `align2', and `align4' methods of
`std.outbuffer.OutBuffer' have been extended to allow specifying a custom
value when pre-filling or padding the buffer.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 60bfa0ee7.
* dmd/VERSION: Update version to v2.100.0.
* d-builtins.cc (d_init_versions): Update for new front-end interface.
* d-codegen.cc (d_decl_context): Use resolvedLinkage to get
declaration linkage.
(build_struct_literal): Track offset in bits.
* d-gimplify.cc (d_gimplify_modify_expr): Check both operands for a
bit-field reference.
* d-lang.cc (d_handle_option): Handle -fpreview=bitfields, remove
-frevert=markdown and -ftransition=vmarkdown.
(d_post_options): Set flag_rtti and flag_exceptions if -fno-druntime
was seen on command-line.
(d_parse_file): Update for new front-end interface.
(d_type_promotes_to): Use resolvedLinkage to get declaration linkage.
* decl.cc (make_thunk): Likewise.
* expr.cc (ExprVisitor::visit (CatAssignExp *)): Remove lowering for
appending of an element or array to another array.
* lang.opt (fpreview=bitfields): New option.
(frevert=markdown): Remove.
(ftransition=vmarkdown): Remove.
* types.cc (layout_aggregate_members): Ignore anonymous fields in
total count.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 94bd5bcb.
* libdruntime/Makefile.am (ALL_DRUNTIME_INSTALL_DSOURCES): Add
$(DRUNTIME_DSOURCES_ELF).
(ALL_DRUNTIME_SOURCES): Likewise.
(DRUNTIME_DSOURCES_ELF): New variable.
* libdruntime/Makefile.in: Regenerate.
* src/MERGE: Merge upstream phobos 3a1cd9a01.
* testsuite/libphobos.init_fini/custom_gc.d: Update test.
136 lines
4.9 KiB
D
136 lines
4.9 KiB
D
/**
|
|
This module contains utility functions to help the implementation of the runtime hook
|
|
|
|
Copyright: Copyright Digital Mars 2000 - 2019.
|
|
License: Distributed under the
|
|
$(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
|
|
(See accompanying file LICENSE)
|
|
Source: $(DRUNTIMESRC core/internal/_array/_utils.d)
|
|
*/
|
|
module core.internal.array.utils;
|
|
|
|
import core.internal.traits : Parameters;
|
|
|
|
auto gcStatsPure() nothrow pure
|
|
{
|
|
import core.memory : GC;
|
|
|
|
auto impureBypass = cast(GC.Stats function() pure nothrow)&GC.stats;
|
|
return impureBypass();
|
|
}
|
|
|
|
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
|
|
{
|
|
import core.internal.traits : externDFunc;
|
|
|
|
alias accumulate = externDFunc!("rt.profilegc.accumulate", void function(string file, uint line, string funcname, string type, ulong sz) @nogc nothrow);
|
|
accumulate(file, line, funcname, name, size);
|
|
return size;
|
|
}
|
|
|
|
auto func = cast(ulong function(string file, int line, string funcname, string name, ulong size) @nogc nothrow pure)&impureBypass;
|
|
return func(file, line, funcname, name, size);
|
|
}
|
|
|
|
/**
|
|
* TraceGC wrapper generator around the runtime hook `Hook`.
|
|
* Params:
|
|
* Type = The type of hook to report to accumulate
|
|
* Hook = The name hook to wrap
|
|
*/
|
|
template TraceHook(string Type, string Hook)
|
|
{
|
|
const char[] TraceHook = q{
|
|
import core.internal.array.utils : gcStatsPure, accumulatePure;
|
|
|
|
pragma(inline, false);
|
|
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 ~ "\".ptr," ~ q{
|
|
file.length, file.ptr,
|
|
line,
|
|
funcname.length, funcname.ptr,
|
|
name.length, name.ptr
|
|
);
|
|
} ~ "}\n" ~ q{
|
|
ulong currentlyAllocated = gcStatsPure().allocatedInCurrentThread;
|
|
|
|
scope(exit)
|
|
{
|
|
ulong size = gcStatsPure().allocatedInCurrentThread - currentlyAllocated;
|
|
if (size > 0)
|
|
if (!accumulatePure(file, line, funcname, name, size)) {
|
|
// This 'if' and 'assert' is needed to force the compiler to not remove the call to
|
|
// `accumulatePure`. It really want to do that while optimizing as the function is
|
|
// `pure` and it does not influence the result of this hook.
|
|
|
|
// `accumulatePure` returns the value of `size`, which can never be zero due to the
|
|
// previous 'if'. So this assert will never be triggered.
|
|
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
|
|
assert(0, errorMessage);
|
|
}
|
|
|
|
/**
|
|
* Check if the function `F` is calleable in a `nothrow` scope.
|
|
* Params:
|
|
* F = Function that does not take any parameters
|
|
* Returns:
|
|
* if the function is callable in a `nothrow` scope.
|
|
*/
|
|
enum isNoThrow(alias F) = is(typeof(() nothrow { F(); }));
|
|
|
|
/**
|
|
* Check if the type `T`'s postblit is called in nothrow, if it exist
|
|
* Params:
|
|
* T = Type to check
|
|
* Returns:
|
|
* if the postblit is callable in a `nothrow` scope, if it exist.
|
|
* if it does not exist, return true.
|
|
*/
|
|
template isPostblitNoThrow(T) {
|
|
static if (__traits(isStaticArray, T))
|
|
enum isPostblitNoThrow = isPostblitNoThrow!(typeof(T.init[0]));
|
|
else static if (__traits(hasMember, T, "__xpostblit") &&
|
|
// Bugzilla 14746: Check that it's the exact member of S.
|
|
__traits(isSame, T, __traits(parent, T.init.__xpostblit)))
|
|
enum isPostblitNoThrow = isNoThrow!(T.init.__xpostblit);
|
|
else
|
|
enum isPostblitNoThrow = true;
|
|
}
|