diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-01-29 21:06:59 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-02-21 15:33:38 +0100 |
commit | f99303eb4aafef70075951731b3ad99266fe6225 (patch) | |
tree | 582ebb6e3e8fd966732bc3b92da1a63caad1aca7 /libphobos/libdruntime | |
parent | 7e9dd9de169034810b92d47bf78284db731fa5da (diff) | |
download | gcc-f99303eb4aafef70075951731b3ad99266fe6225.zip gcc-f99303eb4aafef70075951731b3ad99266fe6225.tar.gz gcc-f99303eb4aafef70075951731b3ad99266fe6225.tar.bz2 |
d: Merge upstream dmd, druntime 09faa4eacd, phobos 13ef27a56.
D front-end changes:
- Import dmd v2.102.0-beta.1
- `static assert' now supports multiple message arguments.
D runtime changes:
- Import druntime v2.102.0-beta.1
- The default `Throwable.TraceInfo' generation now is `@nogc'.
- `Object.factory' method has now been deprecated.
Phobos changes:
- Import phobos v2.102.0-beta.1
- Added float- and double-precision implementations for log
function families in std.math.
- `std.typecons.Unique' now calls `destroy` on struct types
gcc/d/ChangeLog:
* Make-lang.in (D_FRONTEND_OBJS): Add d/location.o.
* d-lang.cc (d_init_options): Update for new front-end interface.
(d_post_options): Call Loc::set after handling options.
* dmd/MERGE: Merge upstream dmd 09faa4eacd.
* dmd/VERSION: Bump version to v2.102.0-beta.1.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 09faa4eacd.
* src/MERGE: Merge upstream phobos 13ef27a56.
* testsuite/libphobos.exceptions/refcounted.d: Add test for chained
reference counted exceptions.
* testsuite/libphobos.shared/finalize.d: Add dg-warning for deprecated
factory interfaces.
* testsuite/libphobos.gc/issue22843.d: New test.
gcc/testsuite/ChangeLog:
* gdc.dg/simd2a.d: Update.
* gdc.dg/simd2b.d: Update.
* gdc.dg/simd2c.d: Update.
* gdc.dg/simd2d.d: Update.
* gdc.dg/simd2e.d: Update.
* gdc.dg/simd2f.d: Update.
* gdc.dg/simd2g.d: Update.
* gdc.dg/simd2h.d: Update.
* gdc.dg/simd2i.d: Update.
* gdc.dg/simd2j.d: Update.
Diffstat (limited to 'libphobos/libdruntime')
-rw-r--r-- | libphobos/libdruntime/MERGE | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/demangle.d | 6 | ||||
-rw-r--r-- | libphobos/libdruntime/core/exception.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d | 14 | ||||
-rw-r--r-- | libphobos/libdruntime/core/internal/gc/impl/manual/gc.d | 7 | ||||
-rw-r--r-- | libphobos/libdruntime/core/runtime.d | 89 | ||||
-rw-r--r-- | libphobos/libdruntime/core/stdc/config.d | 16 | ||||
-rw-r--r-- | libphobos/libdruntime/core/sys/darwin/mach/getsect.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/sys/posix/sys/wait.d | 12 | ||||
-rw-r--r-- | libphobos/libdruntime/core/sys/windows/dbghelp.d | 4 | ||||
-rw-r--r-- | libphobos/libdruntime/core/sys/windows/stacktrace.d | 60 | ||||
-rw-r--r-- | libphobos/libdruntime/core/thread/osthread.d | 12 | ||||
-rw-r--r-- | libphobos/libdruntime/core/time.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/object.d | 19 | ||||
-rw-r--r-- | libphobos/libdruntime/rt/deh.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/rt/dmain2.d | 10 |
16 files changed, 199 insertions, 60 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 5ee6f62..ac3dd12 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -c8ae4adb2eda515b09b326948e3a4aa9f489af45 +09faa4eacd4fb147107e94eeebf56b3a73fdcc05 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d index 869ade6..fe27331 100644 --- a/libphobos/libdruntime/core/demangle.d +++ b/libphobos/libdruntime/core/demangle.d @@ -2134,7 +2134,7 @@ pure @safe: */ char[] demangle(return scope const(char)[] buf, return scope char[] dst = null, CXX_DEMANGLER __cxa_demangle = null) nothrow pure @safe { - if (buf.length > 2 && buf[0..2] == "_Z") + if (__cxa_demangle && buf.length > 2 && buf[0..2] == "_Z") return demangleCXX(buf, __cxa_demangle, dst); auto d = Demangle!()(buf, dst); // fast path (avoiding throwing & catching exception) for obvious @@ -2734,6 +2734,9 @@ unittest s ~= "FiZi"; expected ~= "F"; assert(s.demangle == expected); + + // https://issues.dlang.org/show_bug.cgi?id=23562 + assert(demangle("_Zv") == "_Zv"); } // https://issues.dlang.org/show_bug.cgi?id=22235 @@ -2929,6 +2932,7 @@ CXX_DEMANGLER getCXXDemangler() nothrow @trusted version (FreeBSD) import core.sys.freebsd.dlfcn : RTLD_DEFAULT; version (linux) import core.sys.linux.dlfcn : RTLD_DEFAULT; version (NetBSD) import core.sys.netbsd.dlfcn : RTLD_DEFAULT; + version (OpenBSD) import core.sys.openbsd.dlfcn : RTLD_DEFAULT; version (OSX) import core.sys.darwin.dlfcn : RTLD_DEFAULT; version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT; diff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d index 62179fe..d2016b1 100644 --- a/libphobos/libdruntime/core/exception.d +++ b/libphobos/libdruntime/core/exception.d @@ -278,7 +278,6 @@ class FinalizeError : Error this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super( "Finalization error", file, line, next ); - super.info = SuppressTraceInfo.instance; info = ci; } @@ -393,7 +392,6 @@ class InvalidMemoryOperationError : Error this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super( "Invalid memory operation", file, line, next ); - this.info = SuppressTraceInfo.instance; } override string toString() const @trusted diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d index e29e426..6d19247 100644 --- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d +++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d @@ -110,13 +110,23 @@ alias GC gc_t; /* ============================ GC =============================== */ // register GC in C constructor (_STI_) -extern(C) pragma(crt_constructor) void _d_register_conservative_gc() +private pragma(crt_constructor) void gc_conservative_ctor() +{ + _d_register_conservative_gc(); +} + +extern(C) void _d_register_conservative_gc() { import core.gc.registry; registerGCFactory("conservative", &initialize); } -extern(C) pragma(crt_constructor) void _d_register_precise_gc() +private pragma(crt_constructor) void gc_precise_ctor() +{ + _d_register_precise_gc(); +} + +extern(C) void _d_register_precise_gc() { import core.gc.registry; registerGCFactory("precise", &initialize_precise); diff --git a/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d b/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d index a65c636..570781e 100644 --- a/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d +++ b/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d @@ -29,7 +29,12 @@ static import core.memory; extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */ // register GC in C constructor (_STI_) -extern(C) pragma(crt_constructor) void _d_register_manual_gc() +private pragma(crt_constructor) void gc_manual_ctor() +{ + _d_register_manual_gc(); +} + +extern(C) void _d_register_manual_gc() { import core.gc.registry; registerGCFactory("manual", &initialize); diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d index 799e525..19bb61b 100644 --- a/libphobos/libdruntime/core/runtime.d +++ b/libphobos/libdruntime/core/runtime.d @@ -112,7 +112,7 @@ private alias void delegate( Throwable ) ExceptionHandler; extern (C) void _d_print_throwable(Throwable t); - extern (C) void* thread_stackBottom(); + extern (C) void* thread_stackBottom() nothrow @nogc; } @@ -122,7 +122,7 @@ shared static this() // still possible the app could exit without a stack trace. If // this becomes an issue, the handler could be set in C main // before the module ctors are run. - Runtime.traceHandler = &defaultTraceHandler; + Runtime.traceHandler(&defaultTraceHandler, &defaultTraceDeallocator); } @@ -284,10 +284,18 @@ struct Runtime * If the supplied pointer is null then the trace routine should determine * an appropriate calling context from which to begin the trace. * + * If the deallocator is set, then it is called with the traceinfo when the + * exception is finalized. The deallocator is only set in the exception if + * the default handler is used to generate the trace info. + * * Params: * h = The new trace handler. Set to null to disable exception backtracing. + * d = The new trace deallocator. If non-null, this will be called on + * exception destruction with the trace info, only when the trace + * handler is used to generate TraceInfo. */ - extern(C) pragma(mangle, "rt_setTraceHandler") static @property void traceHandler(TraceHandler h); + extern(C) pragma(mangle, "rt_setTraceHandler") static @property void traceHandler(TraceHandler h, + Throwable.TraceDeallocator d = null); /** * Gets the current trace handler. @@ -298,6 +306,14 @@ struct Runtime extern(C) pragma(mangle, "rt_getTraceHandler") static @property TraceHandler traceHandler(); /** + * Gets the current trace deallocator. + * + * Returns: + * The current trace deallocator or null if none has been set. + */ + extern(C) pragma(mangle, "rt_getTraceDeallocator") static @property Throwable.TraceDeallocator traceDeallocator(); + + /** * Overrides the default collect hander with a user-supplied version. This * routine will be called for each resource object that is finalized in a * non-deterministic manner--typically during a garbage collection cycle. @@ -705,6 +721,10 @@ extern (C) UnitTestResult runModuleUnitTests() * This functions returns a trace handler, allowing to inspect the * current stack trace. * + * IMPORTANT NOTE! the returned trace is potentially not GC allocated, and so + * you must call `defaultTraceDeallocator` when you are finished with the + * `TraceInfo` + * * Params: * ptr = (Windows only) The context to get the stack trace from. * When `null` (the default), start from the current frame. @@ -714,14 +734,24 @@ extern (C) UnitTestResult runModuleUnitTests() * or `null`. If called from a finalizer (destructor), always returns `null` * as trace handlers allocate. */ -Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) +Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) // @nogc { + // NOTE: with traces now being allocated using C malloc, no need to worry + // about GC reentrancy. This code left commented out for reference. + // // avoid recursive GC calls in finalizer, trace handlers should be made @nogc instead - import core.memory : GC; + /*import core.memory : GC; if (GC.inFinalizer) - return null; + return null;*/ - static if (__traits(compiles, new LibBacktrace(0))) + static T allocate(T, Args...)(auto ref Args args) @nogc + { + import core.lifetime : emplace; + import core.stdc.stdlib : malloc; + auto result = cast(T)malloc(__traits(classInstanceSize, T)); + return emplace(result, args); + } + static if (__traits(compiles, allocate!LibBacktrace(0))) { version (Posix) static enum FIRSTFRAME = 4; @@ -729,9 +759,9 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) static enum FIRSTFRAME = 4; else static enum FIRSTFRAME = 0; - return new LibBacktrace(FIRSTFRAME); + return allocate!LibBacktrace(FIRSTFRAME); } - else static if (__traits(compiles, new UnwindBacktrace(0))) + else static if (__traits(compiles, allocate!UnwindBacktrace(0))) { version (Posix) static enum FIRSTFRAME = 5; @@ -739,25 +769,25 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) static enum FIRSTFRAME = 4; else static enum FIRSTFRAME = 0; - return new UnwindBacktrace(FIRSTFRAME); + return allocate!UnwindBacktrace(FIRSTFRAME); } else version (Windows) { import core.sys.windows.stacktrace; - static if (__traits(compiles, new StackTrace(0, null))) + static if (__traits(compiles, allocate!StackTrace(0, null))) { import core.sys.windows.winnt : CONTEXT; version (Win64) enum FIRSTFRAME = 4; else version (Win32) enum FIRSTFRAME = 0; - return new StackTrace(FIRSTFRAME, cast(CONTEXT*)ptr); + return allocate!StackTrace(FIRSTFRAME, cast(CONTEXT*)ptr); } else return null; } - else static if (__traits(compiles, new DefaultTraceInfo())) - return new DefaultTraceInfo(); + else static if (__traits(compiles, allocate!DefaultTraceInfo())) + return allocate!DefaultTraceInfo(); else return null; } @@ -775,9 +805,32 @@ unittest { printf("%.*s\n", cast(int)line.length, line.ptr); } + defaultTraceDeallocator(trace); } } +/*** + * Deallocate a traceinfo generated by deaultTraceHander. + * + * Call this function on a TraceInfo generated via `defaultTraceHandler` when + * you are done with it. If necessary, this cleans up any manually managed + * resources from the `TraceInfo`, and invalidates it. After this, the object + * is no longer valid. + * + * Params: + * info = The `TraceInfo` to deallocate. This should only be a value that + * was returned by `defaultTraceHandler`. + */ +void defaultTraceDeallocator(Throwable.TraceInfo info) nothrow +{ + if (info is null) + return; + auto obj = cast(Object)info; + destroy(obj); + import core.stdc.stdlib : free; + free(cast(void *)obj); +} + version (DRuntime_Use_Libunwind) { import core.internal.backtrace.handler; @@ -791,7 +844,7 @@ else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf import core.stdc.stdlib : free; import core.stdc.string : strlen, memchr, memmove; - this() + this() @nogc { // it may not be 1 but it is good enough to get // in CALL instruction address range for backtrace @@ -805,13 +858,13 @@ else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf elem -= CALL_INSTRUCTION_SIZE; else // backtrace() failed, do it ourselves { - static void** getBasePtr() + static void** getBasePtr() @nogc { version (D_InlineAsm_X86) - asm { naked; mov EAX, EBP; ret; } + asm @nogc { naked; mov EAX, EBP; ret; } else version (D_InlineAsm_X86_64) - asm { naked; mov RAX, RBP; ret; } + asm @nogc { naked; mov RAX, RBP; ret; } else return null; } diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d index c576e99..16bc475 100644 --- a/libphobos/libdruntime/core/stdc/config.d +++ b/libphobos/libdruntime/core/stdc/config.d @@ -286,6 +286,22 @@ private struct _Complex(T) { T re; T im; + + // Helper properties. + pragma(inline, true) + { + static @property epsilon()() { return _Complex(T.epsilon, T.epsilon); } + static @property infinity()() { return _Complex(T.infinity, T.infinity); } + static @property max()() { return _Complex(T.max, T.max); } + static @property min_normal()() { return _Complex(T.min_normal, T.min_normal); } + static @property nan()() { return _Complex(T.nan, T.nan); } + static @property dig()() { return T.dig; } + static @property mant_dig()() { return T.mant_dig; } + static @property max_10_exp()() { return T.max_10_exp; } + static @property max_exp()() { return T.max_exp; } + static @property min_10_exp()() { return T.min_10_exp; } + static @property min_exp()() { return T.min_exp; } + } } enum __c_complex_float : _Complex!float; diff --git a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d index dc42a2d..b6e10a8 100644 --- a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d +++ b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d @@ -148,7 +148,7 @@ version (CoreDdoc) * * auto mph = _NSGetMachExecuteHeader(); * int size; - * assert(getsectdata(mph, "__TEXT", "__text", &size)); + * assert(getsectiondata(mph, "__TEXT", "__text", &size)); * assert(size > 0); * } * --- diff --git a/libphobos/libdruntime/core/sys/posix/sys/wait.d b/libphobos/libdruntime/core/sys/posix/sys/wait.d index 145149b..f6b0674 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/wait.d +++ b/libphobos/libdruntime/core/sys/posix/sys/wait.d @@ -386,9 +386,15 @@ else version (NetBSD) else version (OpenBSD) { enum WCONTINUED = 8; - // OpenBSD does not define the following: - //enum WSTOPPED - //enum WNOWAIT + enum WSTOPPED = WUNTRACED; + enum WNOWAIT = 16; + + enum idtype_t + { + P_ALL, + P_PID, + P_PGID + } } else version (DragonFlyBSD) { diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d index de14bce..55fbc56 100644 --- a/libphobos/libdruntime/core/sys/windows/dbghelp.d +++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d @@ -31,7 +31,7 @@ extern(Windows) alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) SymFunctionTableAccess64Func; alias BOOL function(DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, PVOID ContextRecord, ReadProcessMemoryProc64 ReadMemoryRoutine, FunctionTableAccessProc64 FunctoinTableAccess, - GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) StackWalk64Func; + GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) @nogc StackWalk64Func; alias BOOL function(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, IMAGEHLP_LINEA64 *line) SymGetLineFromAddr64Func; alias DWORD64 function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func; alias BOOL function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULEA64 *ModuleInfo) SymGetModuleInfo64Func; @@ -66,7 +66,7 @@ struct DbgHelp SymRegisterCallback64Func SymRegisterCallback64; ImagehlpApiVersionFunc ImagehlpApiVersion; - static DbgHelp* get() + static DbgHelp* get() @nogc { if ( sm_hndl != sm_hndl.init ) return &sm_inst; diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d index 6e5c4cd..8df2972 100644 --- a/libphobos/libdruntime/core/sys/windows/stacktrace.d +++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d @@ -24,10 +24,10 @@ import core.sys.windows.windef; debug(PRINTF) import core.stdc.stdio; -extern(Windows) void RtlCaptureContext(CONTEXT* ContextRecord); +extern(Windows) void RtlCaptureContext(CONTEXT* ContextRecord) @nogc; extern(Windows) DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR pBuffer, DWORD nSize); -extern(Windows) alias USHORT function(ULONG FramesToSkip, ULONG FramesToCapture, PVOID *BackTrace, PULONG BackTraceHash) RtlCaptureStackBackTraceFunc; +extern(Windows) alias USHORT function(ULONG FramesToSkip, ULONG FramesToCapture, PVOID *BackTrace, PULONG BackTraceHash) @nogc RtlCaptureStackBackTraceFunc; private __gshared RtlCaptureStackBackTraceFunc RtlCaptureStackBackTrace; private __gshared immutable bool initialized; @@ -42,7 +42,7 @@ public: * skip = The number of stack frames to skip. * context = The context to receive the stack trace from. Can be null. */ - this(size_t skip, CONTEXT* context) + this(size_t skip, CONTEXT* context) @nogc { if (context is null) { @@ -64,7 +64,7 @@ public: skip += INTERNALFRAMES; } if ( initialized ) - m_trace = trace(skip, context); + m_trace = trace(tracebuf[], skip, context); } int opApply( scope int delegate(ref const(char[])) dg ) const @@ -100,18 +100,27 @@ public: } /** - * Receive a stack trace in the form of an address list. + * Receive a stack trace in the form of an address list. One form accepts + * an allocated buffer, the other form automatically allocates the buffer. + * * Params: * skip = How many stack frames should be skipped. * context = The context that should be used. If null the current context is used. + * buffer = The buffer to use for the trace. This should be at least 63 elements. * Returns: * A list of addresses that can be passed to resolve at a later point in time. */ static ulong[] trace(size_t skip = 0, CONTEXT* context = null) { + return trace(new ulong[63], skip, context); + } + + /// ditto + static ulong[] trace(ulong[] buffer, size_t skip = 0, CONTEXT* context = null) @nogc + { synchronized( typeid(StackTrace) ) { - return traceNoSync(skip, context); + return traceNoSync(buffer, skip, context); } } @@ -131,38 +140,43 @@ public: } private: + ulong[128] tracebuf; ulong[] m_trace; - static ulong[] traceNoSync(size_t skip, CONTEXT* context) + static ulong[] traceNoSync(ulong[] buffer, size_t skip, CONTEXT* context) @nogc { auto dbghelp = DbgHelp.get(); if (dbghelp is null) return []; // dbghelp.dll not available - if (RtlCaptureStackBackTrace !is null && context is null) + if (buffer.length >= 63 && RtlCaptureStackBackTrace !is null && + context is null) { - size_t[63] buffer = void; // On windows xp the sum of "frames to skip" and "frames to capture" can't be greater then 63 - auto backtraceLength = RtlCaptureStackBackTrace(cast(ULONG)skip, cast(ULONG)(buffer.length - skip), cast(void**)buffer.ptr, null); + version (Win64) + { + auto bufptr = cast(void**)buffer.ptr; + } + version (Win32) + { + size_t[63] bufstorage = void; // On windows xp the sum of "frames to skip" and "frames to capture" can't be greater then 63 + auto bufptr = cast(void**)bufstorage.ptr; + } + auto backtraceLength = RtlCaptureStackBackTrace(cast(ULONG)skip, cast(ULONG)(63 - skip), bufptr, null); // If we get a backtrace and it does not have the maximum length use it. // Otherwise rely on tracing through StackWalk64 which is slower but works when no frame pointers are available. - if (backtraceLength > 1 && backtraceLength < buffer.length - skip) + if (backtraceLength > 1 && backtraceLength < 63 - skip) { debug(PRINTF) printf("Using result from RtlCaptureStackBackTrace\n"); - version (Win64) + version (Win32) { - return buffer[0..backtraceLength].dup; - } - else version (Win32) - { - auto result = new ulong[backtraceLength]; - foreach (i, ref e; result) + foreach (i, ref e; buffer[0 .. backtraceLength]) { - e = buffer[i]; + e = bufstorage[i]; } - return result; } + return buffer[0..backtraceLength]; } } @@ -210,21 +224,21 @@ private: else version (X86_64) enum imageType = IMAGE_FILE_MACHINE_AMD64; else static assert(0, "unimplemented"); - ulong[] result; size_t frameNum = 0; + size_t nframes = 0; // do ... while so that we don't skip the first stackframe do { if (frameNum >= skip) { - result ~= stackframe.AddrPC.Offset; + buffer[nframes++] = stackframe.AddrPC.Offset; } frameNum++; } while (dbghelp.StackWalk64(imageType, hProcess, hThread, &stackframe, &ctxt, null, null, null, null)); - return result; + return buffer[0 .. nframes]; } static char[][] resolveNoSync(const(ulong)[] addresses) diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index 415430c..7316373 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -1997,12 +1997,17 @@ extern (C) void thread_suspendAll() nothrow Thread.criticalRegionLock.lock_nothrow(); scope (exit) Thread.criticalRegionLock.unlock_nothrow(); size_t cnt; + bool suspendedSelf; Thread t = ThreadBase.sm_tbeg.toThread; while (t) { auto tn = t.next.toThread; if (suspend(t)) + { + if (t is ThreadBase.getThis()) + suspendedSelf = true; ++cnt; + } t = tn; } @@ -2010,9 +2015,12 @@ extern (C) void thread_suspendAll() nothrow {} else version (Posix) { - // subtract own thread + // Subtract own thread if we called suspend() on ourselves. + // For example, suspendedSelf would be false if the current + // thread ran thread_detachThis(). assert(cnt >= 1); - --cnt; + if (suspendedSelf) + --cnt; // wait for semaphore notifications for (; cnt; --cnt) { diff --git a/libphobos/libdruntime/core/time.d b/libphobos/libdruntime/core/time.d index ea163a0..8d50875 100644 --- a/libphobos/libdruntime/core/time.d +++ b/libphobos/libdruntime/core/time.d @@ -2822,7 +2822,7 @@ struct TickDuration } - @trusted shared static this() + static pragma(crt_constructor) void time_initializer() { version (Windows) { diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index 83351f2..0385b51 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -246,7 +246,7 @@ class Object * } * --- */ - static Object factory(string classname) + deprecated static Object factory(string classname) { auto ci = TypeInfo_Class.find(classname); if (ci) @@ -256,7 +256,7 @@ class Object return null; } - @system unittest + deprecated @system unittest { Object valid_obj = Object.factory("object.Object"); Object invalid_obj = Object.factory("object.__this_class_doesnt_exist__"); @@ -2481,6 +2481,8 @@ class Throwable : Object string toString() const; } + alias TraceDeallocator = void function(TraceInfo) nothrow; + string msg; /// A message describing the error. /** @@ -2502,6 +2504,12 @@ class Throwable : Object TraceInfo info; /** + * If set, this is used to deallocate the TraceInfo on destruction. + */ + TraceDeallocator infoDeallocator; + + + /** * A reference to the _next error in the list. This is used when a new * $(D Throwable) is thrown from inside a $(D catch) block. The originally * caught $(D Exception) will be chained to the new $(D Throwable) via this @@ -2614,6 +2622,13 @@ class Throwable : Object { if (nextInChain && nextInChain._refcount) _d_delThrowable(nextInChain); + // handle owned traceinfo + if (infoDeallocator !is null) + { + infoDeallocator(info); + info = null; // avoid any kind of dangling pointers if we can help + // it. + } } /** diff --git a/libphobos/libdruntime/rt/deh.d b/libphobos/libdruntime/rt/deh.d index 695f2ce..0a44be3 100644 --- a/libphobos/libdruntime/rt/deh.d +++ b/libphobos/libdruntime/rt/deh.d @@ -42,12 +42,14 @@ module rt.deh; extern (C) { Throwable.TraceInfo _d_traceContext(void* ptr = null); + Throwable.TraceDeallocator rt_getTraceDeallocator(); void _d_createTrace(Throwable t, void* context) { if (t !is null && t.info is null && cast(byte*) t !is typeid(t).initializer.ptr) { t.info = _d_traceContext(context); + t.infoDeallocator = rt_getTraceDeallocator(); } } } diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d index 264fdf6..8a10aac 100644 --- a/libphobos/libdruntime/rt/dmain2.d +++ b/libphobos/libdruntime/rt/dmain2.d @@ -182,6 +182,7 @@ extern (C) int rt_term() */ alias Throwable.TraceInfo function(void* ptr) TraceHandler; private __gshared TraceHandler traceHandler = null; +private __gshared Throwable.TraceDeallocator traceDeallocator = null; /** @@ -189,10 +190,12 @@ private __gshared TraceHandler traceHandler = null; * * Params: * h = The new trace handler. Set to null to use the default handler. + * d = The new dealloactor to use. */ -extern (C) void rt_setTraceHandler(TraceHandler h) +extern (C) void rt_setTraceHandler(TraceHandler h, Throwable.TraceDeallocator d = null) { traceHandler = h; + traceDeallocator = d; } /** @@ -203,6 +206,11 @@ extern (C) TraceHandler rt_getTraceHandler() return traceHandler; } +extern (C) Throwable.TraceDeallocator rt_getTraceDeallocator() +{ + return traceDeallocator; +} + /** * This function will be called when an exception is constructed. The * user-supplied trace handler will be called if one has been supplied, |