Hi,
D has this nice default per-thread static memory model, i.e. if I understand all this correctly, this allows for better, more natural thread safety, while it makes it generally unsafe to use this memory from other threads (without locking). I guess the same is implicitly true for stack memory.
Now could it equally make sense to use per-thread heaps?
I.e. all allocations would need to be per thread, and it would be illegal to reference memory of one thread's heap, static memory, or stack from another thread's memory.
Some RAII locking could pin message-passed (etc.) references temporarily down for them to be used legally by another thread. This would make the sharing of the pointer known to the original thread for a strictly scoped time. Perhaps the synchronized
keyword could be used for these stack references (just a spur of the moment proposal for the purpose of this discussion). Pinning is coupled with message-passing (etc.), i.e. no additional locking required.
For permanent change of ownership i.e. storing a reference in static or heap memory of the other thread, the referenced memory would have to be copied. I.e. there are no synchronized
references from inside static or heap (i.e. non-stack, non-scoped) memory.
I guess synchronized
class objects could get their own, non-thread specific, a.k.a. shared heap (similar in a way to the shared
static memory). All stack references to synchronized
class objects would have to be marked with synchronized
too (or this might be inferred). synchronized
class references stored in other (non-stack, non-scoped) thread memory would still be illegal.
Given the above, the GC could be run per thread. The world would not have to be stopped! Which means that some threads could entirely run without GC while others could still benefit from what I personally think is the only universal and scalable solution to memory safety. As a middle ground, some threads might only use a controlled amount of allocations, therefore GC runs would be super-fast, perhaps still acceptable under (near) real-time performance constrains.
The model would force developers towards a more modularized, per thread (service?) oriented architecture where message passing and lock free programming would be king... (said from a "schoolbook" understanding of these matters ;-)).
Also, I guess the performance of the resulting lock free heap allocs/frees, of the now (by language guarantee) lock free thread safe memory accesses, of the now per thread, smaller and (per definition) lock free GC runs etc. would improve.
Being per-thread i.e. non-preemptive, this could also simplify the GC and allow for more compiler optimizations, I guess. There is no danger of register aliasing and whatnot, that I can only guess makes preemptively interrupting GC correctness under high compiler optimization hard.
Just some thoughts after reading a handful Rust and D books... and after having seen so many wrinkle their noses at GC ... and therefore, unfortunately D.
_Mark