Jump to page: 1 2
Thread overview
compile time garbage collection
May 02, 2015
Freddy
May 02, 2015
ketmar
May 03, 2015
ketmar
May 03, 2015
weaselcat
May 03, 2015
ketmar
May 03, 2015
weaselcat
May 03, 2015
weaselcat
May 03, 2015
deadalnix
May 02, 2015
How crazy hard would it be to have a front end optimization pass that would try to replace garbage collector calls with malloc / free?
May 02, 2015
On Sat, 02 May 2015 15:10:10 +0000, Freddy wrote:

> How crazy hard would it be to have a front end optimization pass that would try to replace garbage collector calls with malloc / free?

impossible.

May 02, 2015
On Saturday, 2 May 2015 at 16:13:36 UTC, ketmar wrote:
> On Sat, 02 May 2015 15:10:10 +0000, Freddy wrote:
>
>> How crazy hard would it be to have a front end optimization pass that
>> would try to replace garbage collector calls with malloc / free?
>
> impossible.

Not impossible, but if you can do it you probably often can replace it with a stack allocation. Though, if D gets "non-shared" semantics right and a high level intermediate representation with whole program optimization then it should be possible to do more. I.e. if you know that an object isn't accessed by another thread ever, then you have something easier to analyze.
May 03, 2015
On Sat, 02 May 2015 16:24:15 +0000, Ola Fosheim Grøstad wrote:

> On Saturday, 2 May 2015 at 16:13:36 UTC, ketmar wrote:
>> On Sat, 02 May 2015 15:10:10 +0000, Freddy wrote:
>>
>>> How crazy hard would it be to have a front end optimization pass that would try to replace garbage collector calls with malloc / free?
>>
>> impossible.
> 
> Not impossible

oh, well, it is possible by adding RC and mark-and-sweep for loops. yet this is cheating, 'cause it's the same old GC in different clothes. ;-)

May 03, 2015
On Saturday, 2 May 2015 at 16:24:17 UTC, Ola Fosheim Grøstad wrote:
> Not impossible, but if you can do it you probably often can replace it with a stack allocation.

AFAIK LDC already has a pass that does this, I'm not sure how well it works.
May 03, 2015
On Sun, 03 May 2015 04:40:42 +0000, weaselcat wrote:

> On Saturday, 2 May 2015 at 16:24:17 UTC, Ola Fosheim Grøstad wrote:
>> Not impossible, but if you can do it you probably often can replace it with a stack allocation.
> 
> AFAIK LDC already has a pass that does this, I'm not sure how well it works.

i don't thing that such pass in general worth the efforts. D programmers tend to use structures for local and short-lived objects. if i did `new`, chances are that i really want it on heap, and it will not be optimisable (i either returning pointer, or passing it to some function that stores it somewhere).

so it can catch very rare cases for the cost of expensive interprocedural analysis. this makes some sense for C++, though.

May 03, 2015
On Sunday, 3 May 2015 at 04:40:44 UTC, weaselcat wrote:
> On Saturday, 2 May 2015 at 16:24:17 UTC, Ola Fosheim Grøstad wrote:
>> Not impossible, but if you can do it you probably often can replace it with a stack allocation.
>
> AFAIK LDC already has a pass that does this, I'm not sure how well it works.

If things do not escape and size is known, it works actually fairly well. Obviously, this kind of thing can only remove some allocations, but most will still ends up being freed by the GC.
May 03, 2015
On Sunday, 3 May 2015 at 04:46:52 UTC, ketmar wrote:
> i don't thing that such pass in general worth the efforts. D programmers
> tend to use structures for local and short-lived objects. if i did `new`,
> chances are that i really want it on heap, and it will not be optimisable

This is where one have to decide whether to make a low/system level language with programmer control or a high level language with compiler control.  If you have GC by default, then it makes a lot of sense to not even have a stack conceptually and do explicit allocations and stack allocation as an optimization.

But yeah, a system level language should allow threads to be terminated which would prevent destructors from being called, and since GC call destructors on another thread it will change program behaviour to turn GC allocations into stack allocations in general...

> so it can catch very rare cases for the cost of expensive interprocedural
> analysis. this makes some sense for C++, though.

Well, if D is to be a higher level language than C++, then it makes more sense for D. Especially since a "threaded view" through "non-shared" objects could allow better analysis, but that would require a 100% ban on transferring "non-shared pointers" to "shared pointers".

D really needs to get a well defined memory model.
May 03, 2015
On Sunday, 3 May 2015 at 08:02:37 UTC, Ola Fosheim Grøstad wrote:
> On Sunday, 3 May 2015 at 04:46:52 UTC, ketmar wrote:
>> i don't thing that such pass in general worth the efforts. D programmers
>> tend to use structures for local and short-lived objects. if i did `new`,
>> chances are that i really want it on heap, and it will not be optimisable
>
> This is where one have to decide whether to make a low/system level language with programmer control or a high level language with compiler control.  If you have GC by default, then it makes a lot of sense to not even have a stack conceptually and do explicit allocations and stack allocation as an optimization.
>
> But yeah, a system level language should allow threads to be terminated which would prevent destructors from being called, and since GC call destructors on another thread it will change program behaviour to turn GC allocations into stack allocations in general...
>

there's no guarantee GC allocated memory will _ever_ have their destructor ran, it's part of the spec.

>The garbage collector is not guaranteed to run the destructor for all unreferenced objects.
May 03, 2015
On Sunday, 3 May 2015 at 08:22:31 UTC, weaselcat wrote:
>
> there's no guarantee GC allocated memory will _ever_ have their destructor ran, it's part of the spec.

That would be very unfortunate, they have to either be called eventually or never called.  I find no such description in the "spec":

http://dlang.org/garbage.html

«5. Freeing all GC allocated memory that has no active pointers to it and do not need destructors to run.

6. Queueing all unreachable memory that needs destructors to run.

7. Resuming all other threads.

8. Running destructors for all queued memory.»
« First   ‹ Prev
1 2