On 30 May 2013 09:25, Johannes Pfau <nos...@example.com> wrote: > Am Thu, 30 May 2013 01:19:10 +0200 > schrieb "Iain Buclaw" <ibuc...@ubuntu.com>: > >> OK, from today till the end of the week I'm going to be sitting >> down and thinking through this, as I'd really like the emitting >> of _tlsstart and _tlsend out of the compiler by hook or by crook. >> >> >> Phase one - start: >> >> We have rt/tls.S. Have added this to the libdruntime builds, and >> I see no immediate problems running this through the testsuite >> (though - that is never really a good indicator of anything). >> Drawbacks, this is only available for linux at the moment. But >> that's fine if we keep this temporary for the week. > > Do you know what that comment in that file "Sadly, this does not work > because ld orders [...]" is about? >
It's the same problem with what we currently have. LD when it gets all reference symbols that are to go into the tls section (for Linux, at least) has the right to reorder the symbols. As such, trying to push _tlsstart as the first symbol in the compiler has no guarantees it will be the first symbol in the object file. >> Phase two - plan: >> >> The GC has a hook gc_addRoot used for the purpose of tracking GC >> allocated memory in C-land. The idea I've got turning over in my >> head at the moment is that any thread local decls that are >> 'new-able' (classes, pointers, d arrays) are added as a root upon >> 'new' declaration, this is safe-guarded by a thread-local static >> to prevent multiple calls to gc_addRoot. >> > > The good part part is that this will work with non-contiguous TLS, i.e > GCC emulated TLS. The bad part is that it'll be very slow so it should > really only be a fallback. And what about non-newable types? > Non-newable types aren't collected because they never reference new memory... This is true for basic types (int, float, complex, vectors). The same is also true for static arrays (although array[] = [1,2,3,4] calls _d_arrayliteral, the allocated memory is copied so can be free'd immediately afterwards). For structures we can check ((TypeStruct *) t)->hasPointers() at compile time - if false then we can be safely assured that this will never be referencing allocated memory. Classes, pointers and D arrays I've already mentioned. Forgot to mention associative arrays, which would also be added as a root upon initialisation. > Why don't we register all thread local variables in a module > constructor instead (in the C one or in the D one)? > > static int a; > static void* b; > > static this() > { > gc_addRoot(&a); > gc_addRoot(&b); > } > This is more of a lazy init that won't affect start-up speed. Note: this idea is based off what C++ (g++) does for say - static A a = new A(); > Then unload in the module destructor. We could try to optimize that, > although we have to be careful: > > static this() //pseudo code > { > void*[2] roots; > roots[0] = &a; > roots[1] = &b; > if(isContiguous(roots[])) //Sort. need to allow alignment though > gc_addRange(roots[0], roots[$] + size) //probably need to keep a > size array as well > else > foreach(ptr; roots) > gc_addRoot(ptr); > } > This is a lot more work to describe in the compiler. :) > This can detect if the TLS memory is contiguous and then only add one > range per module. Maybe it's not worth the effort as long as it's only > a slow fallback (and even with the optimization it'll still be slow) > I don't think it would have much slow down. Albeit the first initialisation would jump through the druntime library twice, but there after it's a single/two instruction test. Pretty negligible - but I'm not a speeeeeeeeed demon or freak who wants everything compiled with -fOMG-fast. =) >> Though this should not be required if we have a proper TLS GC in >> place. > > Do you mean Martin Nowak's shared library/TLS work? That indeed sounds > like the proper solution. > It should certainly mean that we don't have to worry about removing roots once they've been added. > (And maybe the D community should develop a sane standard interface to > the runtime linker to access sections. Then go lobbying all major libcs > out there...) You mean binutils? :-) See binutils/ld/scripttempl for the ldscripts used to lay out the tls data sections. (Note, only a few actually have a TLS section - and only winpe defines a _tls_start__ and _tls_end__ symbol). Regards -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';