[Issue 24336] Downcast to interfaces
https://issues.dlang.org/show_bug.cgi?id=24336 ZombineDev changed: What|Removed |Added CC||petar.p.ki...@gmail.com --
[Issue 24333] Inline ClassInfo with the vtbl
https://issues.dlang.org/show_bug.cgi?id=24333 ZombineDev changed: What|Removed |Added CC||petar.p.ki...@gmail.com --
[Issue 24332] Improve downcast to final classes
https://issues.dlang.org/show_bug.cgi?id=24332 ZombineDev changed: What|Removed |Added CC||petar.p.ki...@gmail.com --
[Issue 24335] Class Downcast
https://issues.dlang.org/show_bug.cgi?id=24335 ZombineDev changed: What|Removed |Added CC||petar.p.ki...@gmail.com --
[Issue 24331] @nogc and GC.disable() are often confused
https://issues.dlang.org/show_bug.cgi?id=24331 --- Comment #6 from Dlang Bot --- dlang/dmd pull request #16023 "fix Issue 24331 - @nogc and GC.disable() are often confused" was merged into master: - e04af29b775a42417d43081fdc905021766b6bb4 by Walter Bright: fix Issue 24331 - @nogc and GC.disable() are often confused https://github.com/dlang/dmd/pull/16023 --
[Issue 24331] @nogc and GC.disable() are often confused
https://issues.dlang.org/show_bug.cgi?id=24331 Dlang Bot changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #5 from Dlang Bot --- dlang/dlang.org pull request #3756 "fix Issue 24331 - @nogc and GC.disable() are often confused" was merged into master: - 5c56620fa0fbfc2db75e681751abbd5f85758cb1 by Walter Bright: fix Issue 24331 - @nogc and GC.disable() are often confused https://github.com/dlang/dlang.org/pull/3756 --
[Issue 24331] @nogc and GC.disable() are often confused
https://issues.dlang.org/show_bug.cgi?id=24331 --- Comment #4 from Dlang Bot --- @WalterBright created dlang/dmd pull request #16023 "fix Issue 24331 - @nogc and GC.disable() are often confused" fixing this issue: - fix Issue 24331 - @nogc and GC.disable() are often confused https://github.com/dlang/dmd/pull/16023 --
[Issue 24331] @nogc and GC.disable() are often confused
https://issues.dlang.org/show_bug.cgi?id=24331 Dlang Bot changed: What|Removed |Added Keywords||pull --- Comment #3 from Dlang Bot --- @WalterBright created dlang/dlang.org pull request #3756 "fix Issue 24331 - @nogc and GC.disable() are often confused" fixing this issue: - fix Issue 24331 - @nogc and GC.disable() are often confused https://github.com/dlang/dlang.org/pull/3756 --
[Issue 24331] @nogc and GC.disable() are often confused
https://issues.dlang.org/show_bug.cgi?id=24331 Walter Bright changed: What|Removed |Added Keywords||industry Hardware|x86 |All OS|Windows |All --
[Issue 24332] Improve downcast to final classes
https://issues.dlang.org/show_bug.cgi?id=24332 Walter Bright changed: What|Removed |Added Keywords||performance --
[Issue 24332] Improve downcast to final classes
https://issues.dlang.org/show_bug.cgi?id=24332 Walter Bright changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24336 --
[Issue 24336] Downcast to interfaces
https://issues.dlang.org/show_bug.cgi?id=24336 Walter Bright changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24332 --
[Issue 24336] Downcast to interfaces
https://issues.dlang.org/show_bug.cgi?id=24336 Walter Bright changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24333 --
[Issue 24333] Inline ClassInfo with the vtbl
https://issues.dlang.org/show_bug.cgi?id=24333 Walter Bright changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24336 --
[Issue 24336] Downcast to interfaces
https://issues.dlang.org/show_bug.cgi?id=24336 Walter Bright changed: What|Removed |Added Keywords||industry, performance --
[Issue 24336] New: Downcast to interfaces
https://issues.dlang.org/show_bug.cgi?id=24336 Issue ID: 24336 Summary: Downcast to interfaces Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: bugzi...@digitalmars.com deadalnix writes: This is getting a bit more tricky, so I won't expand this one fully, but it is also possible to do much better on this front as well. The obvious complication that that interfaces allow for multiple inheritance. The first obvious optimization is to consider the chain of leftmost (or alternatively the longest chain, which allows to cull more candidates faster) inheritance the primaries for the interface and eliminate the whole branch at once using the same strategy as 3/. Now we are left with possible secondaries match. Here, no possibility to remain O(1), we'll have to loop over the other interfaces and repeat the matching process. Thankfully very branch hierarchy are uncommon in practice, but even then, we can use this one weird trick to dramatically cull out the search space: bloom filters. Make the bloom filter 64 bits and simply cull via (targetBloom & aggregateBloom) == targetBloom and you can eliminate a good chunk of the search right there. https://forum.dlang.org/post/hteuczyclxajakris...@forum.dlang.org --
[Issue 24332] Improve downcast to final classes
https://issues.dlang.org/show_bug.cgi?id=24332 Walter Bright changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24335 --
[Issue 24335] Class Downcast
https://issues.dlang.org/show_bug.cgi?id=24335 Walter Bright changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24332 --
[Issue 24335] Class Downcast
https://issues.dlang.org/show_bug.cgi?id=24335 Walter Bright changed: What|Removed |Added Keywords||industry, performance --
[Issue 24335] New: Class Downcast
https://issues.dlang.org/show_bug.cgi?id=24335 Issue ID: 24335 Summary: Class Downcast Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: bugzi...@digitalmars.com deadalnix writes: Currently, we use a linear algorithm to downcast and we reach this algorithm via a call int he runtime. This prevent the optimizer from doing anything about it, in addition to be slow. The problem is similar to 1/. The whole check can be made trivial if we let the compiler prebake some data for us, namely an array of primary parents. Let's see what it looks like in the first example, when b is not final. class A {} class B : A {} auto foo(A a) { return cast(B) a; } Which we can do as follow: auto foo(A a) { // The primaries generated by the compiler for us. auto tidA = typeid(A); assert(tidA.primaries = [tidA]); auto tidB = typeid(B); assert(tidB.primaries = [tidA, tidB]); auto t = typeid(a); auto depth = tidB.primaries.length - 1; if (t.primary.length <= depth) { return null; } if (t.primary[depth] == tidB) { return a; } return null; } This is starting to look good, now we have general downcast in a form that is not only really fast to perform, but also completely transparent to the optimizer. https://forum.dlang.org/post/hteuczyclxajakris...@forum.dlang.org --
[Issue 24334] parameter name is ignored in invocation of struct constructor with default values
https://issues.dlang.org/show_bug.cgi?id=24334 --- Comment #1 from Jim Balter --- P.S. The default constructor works correctly: struct Foo { int a, b = 2, c = 3; } void main() { auto foo = Foo(1, c: 99); imported!"std.stdio".writefln!"a=%s b=%s c=%s"(foo.a, foo.b, foo.c); } output: a=1 b=2 c=99 --
[Issue 24334] New: parameter name is ignored in invocation of struct constructor with default values
https://issues.dlang.org/show_bug.cgi?id=24334 Issue ID: 24334 Summary: parameter name is ignored in invocation of struct constructor with default values Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: major Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: j...@balter.name struct Foo { this(int a, int b = 2, int c = 3) { imported!"std.stdio".writefln!"a=%s b=%s c=%s"(a, b, c); } } void main() { auto foo = Foo(1, c: 99); } Expected output: a=1 b=2 c=99 Actual output: a=1 b=99 c=3 (This bug is dangerous, and quite shocking for a mature language.) Note that the problem is only with a constructor. e.g, this works correctly: struct Bar { static void bar(int a, int b = 2, int c = 3) { imported!"std.stdio".writefln!"a=%s b=%s c=%s"(a, b, c); } } void main() { Bar.bar(1, c: 99); } output: a=1 b=2 c=99 --
[Issue 24333] Inline ClassInfo with the vtbl
https://issues.dlang.org/show_bug.cgi?id=24333 Walter Bright changed: What|Removed |Added Keywords||industry, performance --
[Issue 24333] New: Inline ClassInfo with the vtbl
https://issues.dlang.org/show_bug.cgi?id=24333 Issue ID: 24333 Summary: Inline ClassInfo with the vtbl Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: bugzi...@digitalmars.com deadalnix writes: The current layout of objects is as follow: +---++---++---+ | __vtbl +--->| typeid +--->| ClassInfo | +---++---+| | | __monitor || method0 ||...| +---++---+| | | field0 || method1 |+---+ +---++---+ | field1 ||...| +---++---+ |...| +---+ This causes a ton of extra indirections that are not necessary. instead the following layout ought to be used: +---++---+ | __vtbl +--->| ClassInfo | +---+| | | __monitor ||...| +---+| | | field0 |+---+ +---+| method0 | | field1 |+---+ +---+| method1 | |...|+---+ +---+|...| +---+ Alternatively, it is possible to have the pointer point at the first method and subtract to get the typeid. The important part is that there is only one indirection now. https://forum.dlang.org/post/hteuczyclxajakris...@forum.dlang.org --
[Issue 24332] Improve downcast to final classes
https://issues.dlang.org/show_bug.cgi?id=24332 Walter Bright changed: What|Removed |Added Keywords||industry --
[Issue 24332] New: Improve downcast to final classes
https://issues.dlang.org/show_bug.cgi?id=24332 Issue ID: 24332 Summary: Improve downcast to final classes Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: bugzi...@digitalmars.com deadalnix writes: class A {} final class B : A {} auto foo(A a) { return cast(B) a; } This generates a call into the runtime, making things completely opaque to the optimizer. The algorithm used by the runtime is linear. But there is a dumb constant time solution. because B is final, a is either an instance of B, or it is not (as in, it cannot be an instance of a subclass of B). Therefore, we expect the codegen to look like the following instead: auto foo(A a) { return typeid(a) is typeid(B) ? a : null; } This obviously won't compile but you get the idea. Not only this is constant time, but very simple too, and visible to the optimizer, which means the check can be folded by the opitimizer after other transforms, for instance inlining. https://forum.dlang.org/post/hteuczyclxajakris...@forum.dlang.org Here we go: https://github.com/snazzy-d/sdc/blob/master/test/llvm/downcast.d Except the interface part. --
[Issue 24331] @nogc and GC.disable() are often confused
https://issues.dlang.org/show_bug.cgi?id=24331 timon.g...@gmx.ch changed: What|Removed |Added CC||timon.g...@gmx.ch --- Comment #2 from timon.g...@gmx.ch --- (In reply to Walter Bright from comment #1) > Sounds like better documentation is needed for both @nogc and GC.disable(). Well, currently, the spec states: How Garbage Collection Works - The GC works by: - Stopping all other threads than the thread currently trying to allocate GC memory. - ‘Hijacking’ the current thread for GC work. - Scanning all ‘root’ memory ranges for pointers into GC allocated memory. - Recursively scanning all allocated memory pointed to by roots looking for more pointers into GC allocated memory. - Freeing all GC allocated memory that has no active pointers to it and do not need destructors to run. - Queueing all unreachable memory that needs destructors to run. - Resuming all other threads. - Running destructors for all queued memory. - Freeing any remaining unreachable memory. - Returning the current thread to whatever work it was doing. https://dlang.org/spec/garbage.html So what people are relying on is currently indeed specified behavior. This can of course be changed, but I do not think we can fault users for relying on this documented behavior of the GC. --
[Issue 5573] Compiler (not linker) should generate an error for missing main()
https://issues.dlang.org/show_bug.cgi?id=5573 Dlang Bot changed: What|Removed |Added Keywords||pull --- Comment #4 from Dlang Bot --- @dkorpel created dlang/dmd pull request #16021 "Demangle symbols in linker errors" fixing this issue: - Demangle symbols in linker errors Fix issue 5573 https://github.com/dlang/dmd/pull/16021 --
[Issue 9149] Disallow calling const delegates with a mutable context
https://issues.dlang.org/show_bug.cgi?id=9149 --- Comment #16 from timon.g...@gmx.ch --- (In reply to timon.gehr from comment #11) > > The fix I originally proposed in the first post removes the unsoundness in > the const system, but it is ugly. It means the line "const x = y;" fails if > y is a delegate, but not if y is an instance of a struct wrapping a > delegate. A more elegant solution would be to disallow calling const > delegates whose context is not typed const or immutable. I.e. const(int > delegate()const) can be called, but const(int delegate()) cannot be called. > > Basically the same problem exists for immutable. I updated the title to reflect this more elegant solution. --
[Issue 9149] Disallow calling const delegates with a mutable context
https://issues.dlang.org/show_bug.cgi?id=9149 timon.g...@gmx.ch changed: What|Removed |Added Summary|Disallow converting |Disallow calling const |delegates to const |delegates with a mutable ||context --
[Issue 24331] @nogc and GC.disable() are often confused
https://issues.dlang.org/show_bug.cgi?id=24331 --- Comment #1 from Walter Bright --- Sounds like better documentation is needed for both @nogc and GC.disable(). --
[Issue 24331] New: @nogc and GC.disable() are often confused
https://issues.dlang.org/show_bug.cgi?id=24331 Issue ID: 24331 Summary: @nogc and GC.disable() are often confused Product: D Version: D2 Hardware: x86 OS: Windows Status: NEW Severity: enhancement Priority: P1 Component: dlang.org Assignee: nob...@puremagic.com Reporter: bugzi...@digitalmars.com Adam Wilson writes: @nogc works just fine. We recently spent a good chunk of time in Discord educating a newbie on what it actually does. What @nogc is specified to do: Prevent GC allocations from occurring. Fantastic. What people actually do with @nogc: Use it to selectively disable the GC without using GC.disable(). The reason for this stems from a side-effect of how the current GC operates. Because allocations are the trigger for collections, by preventing allocations, collections are also prevented. And what people really want to do is disable collections because they don't like the collection pauses. They don't actually care about the allocations per se because that is generally as fast as a malloc and they are going to have to allocate at some point anyways. So @nogc works exactly as specified, but because of an unspecified implementation side-effect, that is not guaranteed to hold true in the future, the @nogc crowd writes their code as if @nogc does something else entirely. And we end up here in this thread. --
[Issue 24330] New: Redundant template instantiations for equal string/array literals
https://issues.dlang.org/show_bug.cgi?id=24330 Issue ID: 24330 Summary: Redundant template instantiations for equal string/array literals Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P3 Component: dmd Assignee: nob...@puremagic.com Reporter: dkor...@live.nl ``` void g(string T)() { pragma(msg, "g ", T, " ", T.stringof); } void h(ubyte[] T)() { pragma(msg, "h ", T, " ", T.stringof); } void main() { g!"a"(); g!(['a'])(); h!(cast(ubyte[])"a")(); h!(['a'])(); } ``` Prints: ``` g a "a" g a ['a'] h a "a" h [cast(ubyte)97u] [cast(ubyte)97u] ``` Showing multiple instantiations are made. This is because internally, StringExp and ArrayLiteralExp are hashed/mangled differently. An improvement would be to consistently convert one to the other if possible. --
[Issue 8660] Unclear semantics of array literals of char type, vs string literals
https://issues.dlang.org/show_bug.cgi?id=8660 Dennis changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24330 --
[Issue 24009] The garbage collector tries to allocate memory while the program is out of memory
https://issues.dlang.org/show_bug.cgi?id=24009 Vladimir Panteleev changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24329 --
[Issue 24329] New: GC may not leave any memory for C
https://issues.dlang.org/show_bug.cgi?id=24329 Issue ID: 24329 Summary: GC may not leave any memory for C Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Keywords: industry Severity: normal Priority: P1 Component: druntime Assignee: nob...@puremagic.com Reporter: dlang-bugzi...@thecybershadow.net When the GC tries to allocate some memory and has none available in the pools it already acquired from the OS, it uses a heuristic to decide whether to trigger a collection cycle or to just request more memory from the OS. There are some allocation patterns that may cause it to request the last bit of memory from the OS, even though a collection could otherwise satisfy that demand for memory. When this happens, no more memory can be allocated from anywhere in the program, including from C code using malloc. Though programs generally do not "run out of memory" on modern systems, due to the prevalence of virtual memory, it can still happen if the virtual memory size is limited by `ulimit -v`, or the program runs in a container/cgroup which imposes a memory limit. This becomes a problem when trying to interoperate with C libraries (as most D programs ultimately do). For example, one symptom of this is std.net.curl requests failing with "Out of memory on handle X". Ideally, the GC should stop allocating (if it can avoid doing so) when the total program memory usage approaches the total program memory limit, though querying these two figures may not be straight-forward on all platforms. https://github.com/dlang/dmd/blob/4fc086b0c9d08a5bcdabecdec441ec779462181e/druntime/src/core/internal/gc/os.d#L213-L215 --
[Issue 24328] Very poor GC memory utilization due to fragmentation
https://issues.dlang.org/show_bug.cgi?id=24328 Vladimir Panteleev changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=24329 --
[Issue 24328] Very poor GC memory utilization due to fragmentation
https://issues.dlang.org/show_bug.cgi?id=24328 --- Comment #1 from Vladimir Panteleev --- If I modify the program to use C malloc/free instead of the D GC, I get 81% utilization: // test_c.d // import core.stdc.stdio; import core.stdc.stdlib; enum size_t memoryLimit = 1UL * 1024 * 1024 * 1024; enum size_t allocationSize = 64; @nogc void main() { { import core.sys.posix.sys.resource : rlimit, RLIMIT_AS, getrlimit, setrlimit; rlimit lim; getrlimit(RLIMIT_AS, &lim); lim.rlim_cur = memoryLimit; setrlimit(RLIMIT_AS, &lim); } // Size of reachable data created by this function size_t utilizedSize; scope(exit) printf("Utilized size: %zu (%zd%%)\n", utilizedSize, utilizedSize * 100 / memoryLimit); void** pinned; size_t numPinned; int n; while (true) { void* arr = malloc(allocationSize); if (!arr) { printf("Failed to allocate %zu\n", allocationSize); return; } bool keep = n++ % 2 == 0; if (keep) { auto newSize = (numPinned + 1) * pinned[0].sizeof; pinned = cast(void**)realloc(pinned, newSize); if (!pinned) { printf("Failed to reallocate %zu bytes\n", (numPinned + 1) * pinned[0].sizeof); return; } pinned[numPinned++] = arr; utilizedSize += allocationSize + pinned[0].sizeof; } else free(arr); } } // --
[Issue 24328] New: Very poor GC memory utilization due to fragmentation
https://issues.dlang.org/show_bug.cgi?id=24328 Issue ID: 24328 Summary: Very poor GC memory utilization due to fragmentation Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: normal Priority: P1 Component: druntime Assignee: nob...@puremagic.com Reporter: dlang-bugzi...@thecybershadow.net This program seems to be able to utilize only 2% of memory available to it - the rest seems to be wasted by fragmentation: / test.d import core.stdc.stdio; import core.stdc.stdlib; enum size_t memoryLimit = 1UL * 1024 * 1024 * 1024; enum size_t allocationSize = 64; void main() { { import core.sys.posix.sys.resource : rlimit, RLIMIT_AS, getrlimit, setrlimit; rlimit lim; getrlimit(RLIMIT_AS, &lim); lim.rlim_cur = memoryLimit; setrlimit(RLIMIT_AS, &lim); } // Size of reachable data created by this function size_t utilizedSize; scope(exit) printf("Utilized size: %zu (%zd%%)\n", utilizedSize, utilizedSize * 100 / memoryLimit); ubyte[][] pinned; int n; while (true) { ubyte[] arr; { scope(failure) printf("Failed to allocate %zu\n", allocationSize); arr = new ubyte[allocationSize]; } bool keep = n++ % 2 == 0; if (keep) { { scope(failure) printf("Failed to reallocate %zu bytes\n", (pinned.length + 1) * pinned[0].sizeof); pinned ~= arr; } utilizedSize += allocationSize + pinned[0].sizeof; } } } / --
[Issue 24327] LDC --nogc should work for scope class instance
https://issues.dlang.org/show_bug.cgi?id=24327 --- Comment #1 from a11e99z --- BTW I prefer: auto c = scope C(); cuz new X means heap/GC, scope means scope --