February 06, 2016
On Saturday, 6 February 2016 at 17:36:28 UTC, Ola Fosheim Grøstad wrote:
> On Saturday, 6 February 2016 at 17:22:03 UTC, Adam D. Ruppe wrote:
>> On Saturday, 6 February 2016 at 11:15:06 UTC, Ola Fosheim Grøstad wrote:
>>> Nothing prevents you from creating your own reference counting mechanism.
>>
>> A struct wrapper doesn't give the things you need to reliably handle inheritance.
>
> I don't think I suggested using a struct wrapper? :-) That just cause issues with alignment or requires a more complex allocator.
>
> You can either build the refcount into the root class or use an extra indirection like C++'s shared_ptr.

Can't be done with the root class because classes never trigger RAII outside of (deprecated) scope allocations.
Can't be done with indirection because you still hit the same issue.
Applies to storage classes aswell, btw.
February 06, 2016
On Saturday, 6 February 2016 at 17:38:30 UTC, rsw0x wrote:
> Can't be done with the root class because classes never trigger RAII outside of (deprecated) scope allocations.

Not sure what you mean. The class instance doesn't have to trigger anything?

You "retain(instance)" to increase the refcount and "release(instance)" to decrease refcount or destroy the instance.

February 06, 2016
On Saturday, 6 February 2016 at 17:46:00 UTC, Ola Fosheim Grøstad wrote:
> On Saturday, 6 February 2016 at 17:38:30 UTC, rsw0x wrote:
>> Can't be done with the root class because classes never trigger RAII outside of (deprecated) scope allocations.
>
> Not sure what you mean. The class instance doesn't have to trigger anything?
>
> You "retain(instance)" to increase the refcount and "release(instance)" to decrease refcount or destroy the instance.

Might as well manually free and delete instead.
February 06, 2016
On Saturday, 6 February 2016 at 17:46:48 UTC, rsw0x wrote:
> On Saturday, 6 February 2016 at 17:46:00 UTC, Ola Fosheim Grøstad wrote:
>> On Saturday, 6 February 2016 at 17:38:30 UTC, rsw0x wrote:
>>> Can't be done with the root class because classes never trigger RAII outside of (deprecated) scope allocations.
>>
>> Not sure what you mean. The class instance doesn't have to trigger anything?
>>
>> You "retain(instance)" to increase the refcount and "release(instance)" to decrease refcount or destroy the instance.
>
> Might as well manually free and delete instead.

Er, malloc and free* : )
February 06, 2016
On Saturday, 6 February 2016 at 17:46:48 UTC, rsw0x wrote:
> Might as well manually free and delete instead.

Not really, this was used in Objective-C before ARC.

But you can always move retain/release/borrow/unborrow into your own pointer struct like shared_ptr.

February 06, 2016
On Saturday, 6 February 2016 at 10:29:32 UTC, Ola Fosheim Grøstad wrote:
> This prevents fast GC: Pointers.

Would it be possible to write a fast garbage collector that just didn't track any pointers? Just offer a head's up that if you use "this collector" and pointers on collectable data, you're gonna have a bad time? How limited would you be if you couldn't use pointers in your code? Do all D references count as pointers, or is it only the T* types? Does Nullable!T count as one of those pointers that can't be tracked quickly?
February 06, 2016
On Saturday, 6 February 2016 at 22:41:28 UTC, cy wrote:
> On Saturday, 6 February 2016 at 10:29:32 UTC, Ola Fosheim Grøstad wrote:
>> This prevents fast GC: Pointers.
>
> Would it be possible to write a fast garbage collector that just didn't track any pointers? Just offer a head's up that if you use "this collector" and pointers on collectable data, you're gonna have a bad time? How limited would you be if you couldn't use pointers in your code? Do all D references count as pointers, or is it only the T* types?

Yes, all references to gc allocated memory. "fast" is perhaps the wrong word, Go has a concurrent collector with low latency pauses, but requires slower code for mutating pointers since another thread is collwcting garbage at the same time.

Things that could speed up collection:
- drop destructors so you don't track dead objects
- require pointers to beginning of gc object and make them a special type, so you scan less
- use local heaps and local collection per fiber
- change layout so pointers end up on the same cachelines





February 07, 2016
Am Sat, 06 Feb 2016 11:47:02 +0000
schrieb Ola Fosheim Grøstad
<ola.fosheim.grostad+dlang@gmail.com>:

> Of course, Swift does not aim for very high performance, but for convenient application/gui development. And frankly JavaScript is fast enough for that kind of programming.

My code would not see much ref counting in performance critical
loops. There is no point in ref counting every single point in
a complex 3D scene.
I could imagine it used on bigger items. Textures for example
since they may be used by several objects. Or - a prime
example - any outside resource that is potentially scarce and
benefits from deterministic release: file handles, audio
buffers, widgets, ...

-- 
Marco

February 07, 2016
Am Sat, 06 Feb 2016 23:18:59 +0000
schrieb Ola Fosheim Grøstad
<ola.fosheim.grostad+dlang@gmail.com>:

> Things that could speed up collection:
> - drop destructors so you don't track dead objects

Interesting, that would also finally force external resources off the GC heap and into deterministic release. That needs a solution to inheritance though. Think widget kits.

-- 
Marco

February 07, 2016
On Sunday, 7 February 2016 at 02:46:39 UTC, Marco Leise wrote:
> My code would not see much ref counting in performance critical
> loops. There is no point in ref counting every single point in
> a complex 3D scene.
> I could imagine it used on bigger items. Textures for example
> since they may be used by several objects. Or - a prime
> example - any outside resource that is potentially scarce and
> benefits from deterministic release: file handles, audio
> buffers, widgets, ...

In my experience most such resources don't need reference counting. Yes, Textures if you load dynamically, but if you load Textures before entering the render loop... not so much and it should really be a caching system so you don't have to reload the texture right after freeing it. File handles are better done as single borrow from owner, or pass by reference, you don't want multiple locations to write to the same file handle, audio buffers should be preallocated as they cannot be deallocated cheaply on the real time thread, widgets benefit more from weak-pointers/back-pointers-to-borrowers as they tend to have a single owning parent...

What would be better is to build better generic static analysis and optimization into the compiler. So that the compiler can deduce that an integer is never read except when decremented, and therefore can elide inc/dec pairs.