February 05, 2014
On 6 February 2014 02:16, Dicebot <public@dicebot.lv> wrote:

> On Wednesday, 5 February 2014 at 16:13:33 UTC, Manu wrote:
>
>> Huh? Why would they? They don't create cycles, and would clean up reliably.
>>
>
> Because they still return T* and not RC!T ? Andrei's post speaks purely about extra library type and does not mention about possibility to make it default allocation type for language.
>
> Or it is just silently assumed?
>

Dunno, but I don't think any solution which uses RC!T will ever be acceptable. It basically defeats the whole purpose.


February 05, 2014
On Wednesday, 5 February 2014 at 17:40:35 UTC, Manu wrote:
> Dunno, but I don't think any solution which uses RC!T will ever be
> acceptable. It basically defeats the whole purpose.

I feel terribly confused now :(

Andrei, can you describe your intention with some big picture context?
February 05, 2014
On 2/5/14, 1:05 AM, Adam Wilson wrote:
> On Tue, 04 Feb 2014 23:38:54 -0800, Kagamin <spam@here.lot> wrote:
>
>> My understanding was that ARC completely replaces GC and everything
>> including slices becomes refcounted. Is having mixed incompatible GC
>> and ARC code and trying to get them interoperate a good idea? Can you
>> sell such mixed code to ARC guys?
>
> I've been asking myself those questions a lot over the past couple days.
> If GC backed ARC is such a brilliant idea, how come nobody has done it
> yet?

It's a classic.

Andrei

February 05, 2014
On Wednesday, 5 February 2014 at 17:24:46 UTC, Ola Fosheim Grøstad wrote:
> The access would be easy and something like (probably not 100% correct):
>
> counter_addr = (ptr&~0xffff) + ( (ptr>>12)&0xfffc )

It was of course wrong, that would make the smallest allocation unit 16KiB. Anyway, if tuned to the indexed loads of the CPU then it would not be all the slow. On the x86 you should be able to do something like (pseudo):

uint64 reg1 = ptr & 0xfff....f0000
uint32 reg2 = ptr >> 8
uint64 reg3 = load_effective_address( reg1 + 4*reg2 )
increment( *reg3 )

So only 4-5 cheap instructions for single threaded counting.

You could also use the most significant bit for bookkeeping of single-threaded vs multi-threaded ref counting:

   test (*reg3)
   if (positive) goto nolock:
   lockprefix
nolock:
   increment( *reg3 )
February 05, 2014
On 2/5/14, 4:39 AM, Manu wrote:
> On 5 February 2014 09:51, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org <mailto:SeeWebsiteForEmail@erdani.org>>
> wrote:
>
>     Consider we add a library slice type called RCSlice!T. It would have
>     the same primitives as T[] but would use reference counting through
>     and through. When the last reference count is gone, the buffer
>     underlying the slice is freed. The underlying allocator will be the
>     GC allocator.
>
>     Now, what if someone doesn't care about the whole RC thing and aims
>     at convenience? There would be a method .toGC that just detaches the
>     slice and disables the reference counter (e.g. by setting it to
>     uint.max/2 or whatever).
>
>     Then people who want reference counting say
>
>     auto x = fun();
>
>     and those who don't care say:
>
>     auto x = fun().toGC();
>
>
>     Destroy.
>
>
> This doesn't excite me at all.
> What about all other types of allocations? I don't want to mangle my
> types.

How do you mean that?

> What about closures?

This is "#1" and it only addresses slices.

> What about allocations from phobos?

Phobos would get added support for RC slices.

> What
> about allocations from 3rd party libs that I have no control over?

Outside the charter of this discussion.

> I don't like that it requires additional specification, and special
> treatment to have it detach to the GC.

But you didn't like that GC is implicit. Which way do you want it?

> There's nothing transparent about that.

I don't think we can attain 100% transparency.

> Another library solution like
> RefCounted doesn't address the problem.
>
> Counter question; why approach it this way?
> Is there a reason that it needs to be of one kind or the other?

This is technically possible today.


Andrei

February 05, 2014
On 2/5/14, 7:10 AM, Dicebot wrote:
> On Tuesday, 4 February 2014 at 23:51:35 UTC, Andrei Alexandrescu wrote:
>> ...
>>
>> Destroy.
>>
>> Andrei
>
> I simply don't understand what problem this is trying to solve.

Allow people to clean up memory allocated by Phobos.

Andrei
February 05, 2014
On 2/5/14, 7:23 AM, Michel Fortin wrote:
> On 2014-02-04 23:51:35 +0000, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> said:
>
>> Consider we add a library slice type called RCSlice!T. It would have
>> the same primitives as T[] but would use reference counting through
>> and through. When the last reference count is gone, the buffer
>> underlying the slice is freed. The underlying allocator will be the GC
>> allocator.
>>
>> Now, what if someone doesn't care about the whole RC thing and aims at
>> convenience? There would be a method .toGC that just detaches the
>> slice and disables the reference counter (e.g. by setting it to
>> uint.max/2 or whatever).
>>
>> Then people who want reference counting say
>>
>> auto x = fun();
>>
>> and those who don't care say:
>>
>> auto x = fun().toGC();
>>
>>
>> Destroy.
>
> I don't think it makes much sense. ARC when used for D constructs should
> be treated an alternate GC algorithm, not a different kind of pointer.

Why? The RC object has a different layout, so it may as well have a different type.

Andrei
February 05, 2014
On 2/5/14, 9:40 AM, Manu wrote:
> On 6 February 2014 02:16, Dicebot <public@dicebot.lv
> <mailto:public@dicebot.lv>> wrote:
>
>     On Wednesday, 5 February 2014 at 16:13:33 UTC, Manu wrote:
>
>         Huh? Why would they? They don't create cycles, and would clean
>         up reliably.
>
>
>     Because they still return T* and not RC!T ? Andrei's post speaks
>     purely about extra library type and does not mention about
>     possibility to make it default allocation type for language.
>
>     Or it is just silently assumed?
>
>
> Dunno, but I don't think any solution which uses RC!T will ever be
> acceptable.

Why not? What would be deemed acceptable? And who's the acceptor?

> It basically defeats the whole purpose.

What is the purpose?


Andrei

February 05, 2014
On 2/5/14, 9:51 AM, Dicebot wrote:
> On Wednesday, 5 February 2014 at 17:40:35 UTC, Manu wrote:
>> Dunno, but I don't think any solution which uses RC!T will ever be
>> acceptable. It basically defeats the whole purpose.
>
> I feel terribly confused now :(
>
> Andrei, can you describe your intention with some big picture context?

Phobos needs to be able to return allocated memory without creating litter. With RCSlice!T the ownership is passed back to the user. The user can continue tracking it by using reference counting built into RCSlice, or make the object "immortal" by calling .toGC against it.

It's simple, really. All about libraries returning (and sometimes accepting) slices.


Andrei

February 05, 2014
How would look the syntax for creating a RC slice?
int[] arr = new int[100];
or
somewhat ugly as RCSlice!int arr = new int[100];
?
Or (as I fear) RCSlice!int arr = RCSlice!int(100); ?