December 18, 2022

On Saturday, 17 December 2022 at 18:44:21 UTC, IGotD- wrote:

>

I see concurrent GC (or at least something that doesn't stop other threads) as the only choice. The more I look into the D garbage collector the more surprised I become.

I wouldn't say it is is the only choice. If D was willing to make a bold move towards modelling software as short lived actors/tasks then you could use arenas that typically don't collect, but is wiped out when the task is done (collection only happens if you run out of memory).

Right now I am personally more interested in Carbon that will be 100% GC free. I like that they take a stance on memory management overhead. There are also interesting things going on in the research field with separation logic and similar formalizations, still probably 20 years until it will be generally useful, but things are moving IMO. There is also some interest in memory pools/arenas in the C++ community I think, and there seems to be an interest in Apple for integrating C++ and Swift, so maybe pairing one managed and one unmanaged language is the way forward, short term. So overall, the global picture is nuanced.

>
  1. Scan the stack from the stack pointer and upwards.
  2. Scan all the registers, making the algorithm non portable.
  3. Scan all the globally allocated memory
  4. Scan all the thread local storage. This usually live on the stack for the libraries that are loaded at startup. This information must be read out before or after the thread starts.
  5. The threads that were interrupted, the context must be read out including the position of the stack pointer.

Application specific collectors don't have to do all this work as they will only collect at specific points where the state is known and where the number of live objects are minimal. This is something one should be able to use verification technologies for, basically proving that there are no stray references hanging around when you start collecting. Rust is only the beginning I think.

>
  1. You need metadata for the tracing graph. D uses typeinfo in order to reduce the scanning of objects, this is nice but at the same increases the complexity.

You could probably generate a hardcoded "optimal" scanner statically at linktime after LTO, but that only makes it somewhat faster, and not really better.

>

making this possible. It's not completely straight forward and suspending all threads require quite different approaches on each system. What if they didn't?

Suspending all threads, for whatever reason, is a terrible idea. Just think about Amdahl's law:

https://en.wikipedia.org/wiki/Amdahl%27s_law#/media/File:AmdahlsLaw.svg

>

So the question if GC is built into the standard library is positive or negative, then my answer is that in the case of the D it certainly increase the complexity quite a lot. What if there was a simpler path?

ARC.

December 19, 2022

On Sunday, 18 December 2022 at 22:11:21 UTC, Ola Fosheim Grøstad wrote:

>

On Saturday, 17 December 2022 at 18:44:21 UTC, IGotD- wrote:

>

[...]

I wouldn't say it is is the only choice. If D was willing to make a bold move towards modelling software as short lived actors/tasks then you could use arenas that typically don't collect, but is wiped out when the task is done (collection only happens if you run out of memory).

Right now I am personally more interested in Carbon that will be 100% GC free. I like that they take a stance on memory management overhead. There are also interesting things going on in the research field with separation logic and similar formalizations, still probably 20 years until it will be generally useful, but things are moving IMO. There is also some interest in memory pools/arenas in the C++ community I think, and there seems to be an interest in Apple for integrating C++ and Swift, so maybe pairing one managed and one unmanaged language is the way forward, short term. So overall, the global picture is nuanced.

>

[...]

Application specific collectors don't have to do all this work as they will only collect at specific points where the state is known and where the number of live objects are minimal. This is something one should be able to use verification technologies for, basically proving that there are no stray references hanging around when you start collecting. Rust is only the beginning I think.

>

[...]

You could probably generate a hardcoded "optimal" scanner statically at linktime after LTO, but that only makes it somewhat faster, and not really better.

>

[...]

Suspending all threads, for whatever reason, is a terrible idea. Just think about Amdahl's law:

https://en.wikipedia.org/wiki/Amdahl%27s_law#/media/File:AmdahlsLaw.svg

>

[...]

ARC.

When all is said and done, I think we should try to provide lifetimes as a feature, simply because C++ might be offering them, and we will need to accomodate that for the sake of C++ interop anyways, else risk deteriorating our C++ interop story

I know having a proposal means very little, but I have a feeling that it's a question of when, not if, C++ receives lifetime annotations

December 21, 2022

On Friday, 16 December 2022 at 13:56:19 UTC, bauss wrote:

>

On Friday, 16 December 2022 at 13:25:25 UTC, Nick Treleaven wrote:

>

This pull disallows throwing an immutable object:

https://github.com/dlang/dmd/pull/14706

You can still throw a const object though, which would work for your enforce.

Of course that was changed as immutable can convert to const before throwing, and const shouldn't be violated even if not immutable.

>

Personally I think it should always just be implied const like:

catch (Exception e) should imply catch (const e) that way both mutable and immutable will work.

That solves the throw/catch qualifier mismatch problem, but it still can violate immutable when the runtime sets the stack trace. Also not sure if the runtime may set another field. If reference counted exceptions are implemented then that might conflict with const/immutable too (though it can be worked around with a hashtable).

December 21, 2022

On Wednesday, 21 December 2022 at 12:44:18 UTC, Nick Treleaven wrote:

>

On Friday, 16 December 2022 at 13:56:19 UTC, bauss wrote:

>

On Friday, 16 December 2022 at 13:25:25 UTC, Nick Treleaven wrote:

>

This pull disallows throwing an immutable object:

https://github.com/dlang/dmd/pull/14706

You can still throw a const object though, which would work for your enforce.

Of course that was changed as immutable can convert to const before throwing, and const shouldn't be violated even if not immutable.

Using const is not an undefined behavior, but it's still not safe and not desirable. Because we have to hope that the catch blocks never try to modify the received exception object and never let it escape the catch block scope. This makes immutable a much better fit.

> >

Personally I think it should always just be implied const like:

catch (Exception e) should imply catch (const e) that way both mutable and immutable will work.

That solves the throw/catch qualifier mismatch problem, but it still can violate immutable when the runtime sets the stack trace.

If a custom Throwable.TraceInfo is already set (see https://forum.dlang.org/post/bvgalazssljjnchqnjso@forum.dlang.org as an example), then the runtime does not try to modify it. This is valid for a wide range of the older versions of the D compiler & druntime up to and including the most recent v2.101.1 (but the future versions may of course change).

>

Also not sure if the runtime may set another field.

To the best of my knowledge, it doesn't. Tested by valgrind in this way and also looked at the druntime code.

>

If reference counted exceptions are implemented then that might conflict with const/immutable too (though it can be worked around with a hashtable).

The reference counted exceptions are already implemented and can be previewed by using the -dip1008 command line option for DMD or the -fpreview=dip1008 command line option for GDC (only GDC12 or newer). The current implementation checks the reference counter here and only increments it if it's non-zero. The zero value of the reference counter means that it is GC allocated (this works fine for static immutable exception instances too).

I have no clue if there are any plans to make -dip1008 available by default any time soon and its status is "Postponed". I'm not sure if anything other than https://github.com/dlang/dmd/pull/14710 is preventing this from happening. If anyone is aware of any other DIP1008 blockers, then please let me know.

1 2 3 4 5 6
Next ›   Last »