On 17-10-2012 13:51, Jacob Carlborg wrote:
On 2012-10-17 10:55, Alex Rønne Petersen wrote:

Let's step back for a bit and think about what we want to achieve with
thread-local garbage collection. The idea is that we look only at a
single thread's heap (and stack/registers, of course) when doing a
collection. This means that we can -- theoretically -- stop only one
thread at a time and only when it needs to be stopped. This is clearly a
huge win in scalability and raw speed. With a scheme like this, it might
even be possible to get away with a simple mark-sweep or copying GC per
thread instead of a complicated generational GC, mainly due to the
paradigms the isolation model induces.

Rust, as it is today, can do this. Tasks (or threads if you will -
though they aren't the same thing) are completely isolated. Types that
can potentially contain pointers into a task's heap cannot be sent to
other tasks at all. Rust also does not have global variables.

So, let's look at D:

1. We have global variables.
1. Only std.concurrency enforces isolation at a type system level; it's
not built into the language, so the GC cannot make assumptions.
1. The shared qualifier effectively allows pointers from one thread's
heap into another's.

It's important to keep in mind that in order for thread-local GC (as
defined above) to be possible at all, *under no circumstances whatsoever
must there be a pointer in one thread's heap into another thread's heap,
ever*. If this happens and you apply the above GC strategy (stop one
thread at a time and scan only that thread's heap), you're effectively
dealing with something very similar to the lost object problem on
concurrent GC.

To clarify with regards to the shared qualifier: It does absolutely
nothing. It's useless. All it does is slap a pretty "I can be shared
arbitrarily across threads" label on a type. Even if you have this
knowledge in the GC, it's not going to help you, because you *still*
have to deal with the problem that arbitrary pointers can be floating
around in arbitrary threads.

(And don't even get me started on the lack of clear semantics (and even
the few semi-agreed-upon but flawed semantics) for shared.)

All TLS data is handled by collectors running in their one single
thread, as you describe above. Any non-TLS data is handled the same way
as the GC currently works.

This is how the, now deprecated, Apple GC used by Objective-C works.


How does it deal with the problem where a pointer in TLS points to global data, or worse yet, a pointer in the global heap points to TLS?

I'm pretty sure it can't without doing a full pass over the entire heap, which seems to me like it defeats the purpose.

But I may just be missing out on some restriction (type system or whatever) Objective-C has that makes it feasible.

--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org

Reply via email to