February 05, 2014
On Wednesday, 5 February 2014 at 19:09:57 UTC, Marco Leise wrote:
>> You could put in a function pointer to a deallocator (c-malloc, QT, GTK or some other library deallocator etc) and other kind of meta information that makes you able to treat reference counting in a uniform manner even for external resources.
>
> Now that sounds interesting.

It sounds to me like... a separate type. The deallocator is the destructor!
February 05, 2014
On Wednesday, 5 February 2014 at 19:04:10 UTC, Namespace wrote:
> Would it not be possible to add an "int rc" to the internal Array struct? So that int[] arr = [1, 2, 3]; is ref counted per default?

Please no (it'd also have to be int* rc btw). This makes slices fatter than they need to be.

We should be looking at reducing costs, not shuffling them around or adding to them.

February 05, 2014
On Wednesday, 5 February 2014 at 19:13:01 UTC, Adam D. Ruppe wrote:
> It sounds to me like... a separate type. The deallocator is the destructor!

Yes, but "destructor" of the reference counter object is "decrease count by one", when it goes to zero. Not when it is destroyed.

Sure, you can use classes for it, but I don't think you want to. It is better to have a uniform reference counter object that can be fully inlined with no function calls as the general case and then only call the external "deallocator" with itself as parameter when it is present.
February 05, 2014
On Wednesday, 5 February 2014 at 19:15:41 UTC, Adam D. Ruppe wrote:
> On Wednesday, 5 February 2014 at 19:04:10 UTC, Namespace wrote:
>> Would it not be possible to add an "int rc" to the internal Array struct? So that int[] arr = [1, 2, 3]; is ref counted per default?
>
> Please no (it'd also have to be int* rc btw). This makes slices fatter than they need to be.
>
> We should be looking at reducing costs, not shuffling them around or adding to them.

Only if you change the current implementation from this:
----
struct Array {
	void* ptr;
	size_t length;
}
----
to this:
----
struct Array {
	void* ptr;
        int* rc;
	size_t length;
}
----
But we could also implement it like this:
----
struct Array {
	static struct Payload {
		void* ptr;
		int* rc;
	}

	Payload* p;
	size_t length;
}
----
with the same costs.
February 05, 2014
On 2/5/14, 10:45 AM, "Ola Fosheim Grøstad" <ola.fosheim.grostad+dlang@gmail.com>" wrote:
> On Wednesday, 5 February 2014 at 18:33:54 UTC, Andrei Alexandrescu wrote:
>> 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.
>
> Would it be possible to use RCSlice for all reference counting? I.e.
> that a reference counter for a struct would be a RCSlice of fixed length 1?
>
> If so then maybe it would be nice, but with a different name.

This is only focusing on slices.

Andrei
February 05, 2014
On 2/5/14, 10:55 AM, Dicebot wrote:
> On Wednesday, 5 February 2014 at 18:33:54 UTC, Andrei Alexandrescu wrote:
>> 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.
>
> Ok, clear. It will work then as far as I can see.
>
> But I am surprised this is considered a #1 issue to address.

"#1" as in "the first idea that came to mind". Just sorting by date :o).

> I have
> never been worried by lack of control over generated garbage in Phobos -
> it was the other way around, worries about control of how it is allocated.
>
> So yes, this is likely to solve issue you have mentioned but does not
> seem to be of any interest to me.

Noted. That part needs to be addressed by allocators.


Andrei

February 05, 2014
On 2/5/14, 10:56 AM, Adam D. Ruppe wrote:
> On Wednesday, 5 February 2014 at 18:25:31 UTC, Andrei Alexandrescu wrote:
>> Allow people to clean up memory allocated by Phobos.
>
> A better solution would be for Phobos to allocate less memory. Instead
> of returning strings, accept output ranges that receive it.

You do figure that complicates usage considerably, right?

> Make slices
> work as output ranges well with control over growing.
>
> (We can still offer the simple string returning functions for convenience)

I was thinking RCSlice would be a better alternative.


Andrei
February 05, 2014
On Wednesday, 5 February 2014 at 19:36:00 UTC, Namespace wrote:
> 	static struct Payload {
> 		void* ptr;
> 		int* rc;
> 	}
>
> 	Payload* p;

Now there's double indirection to get to the data... and you also forgot the necessary postblits and dtors to maintain the reference count. (these could be inlined or elided in some cases, but not all)

You can't put the rc at the beginning of the pointer either, since then a = a[1..$] won't work. So the added pointer is unavoidable, your way or my way, both have a cost.
February 05, 2014
I'm just a casual end-user of D, but have been following this and related discussions with great interest. Just yesterday I was trying to "sell" D to a friend, and he basically told me that he'd be interested once the memory management situation gets resolved. I've been thinking about this a lot lately, even though I'm probably way out of my depth given the experts that frequent this forum. Still, I had an idea about this and thought I'd throw it out there.

On Wednesday, 5 February 2014 at 04:18:49 UTC, Andrei Alexandrescu wrote:
> On 2/4/14, 5:12 PM, deadalnix wrote:
>> That being understood, I'd rather connect things the other way around.
>>
>> auto x = foo();
>> auto x = foo().toRC();
>
> I don't know how to implement that.
>
>
> Andrei

From the discussion currently going on about postblits, it seems like there's a new emerging concept of a "unique expression," the value of which is guaranteed not to be referenced elsewhere. Could this concept perhaps be leveraged to go backwards from GC to RC? If you perform a GC allocation in the context of a unique expression, would it then be safe to force it back into an RC context, knowing that there are no outstanding references to it? What's more, it would allow library writes to mostly perform allocations a single way, giving the choice to the caller how they'd like to manage the lifetime of the newly returned unique object.

I could be completely misunderstanding the unique-expression concept though.
February 05, 2014
On Wednesday, 5 February 2014 at 19:37:29 UTC, Andrei Alexandrescu wrote:
> This is only focusing on slices.

That is not going to work out well, because you should be able to decrease the ref count of a pointer to something arbitrary (void) without knowing the object type. And the ref count object should persist after destruction of the object in the case of weak pointers.