Keeping a list of instances and garbage-collection

Bill Baxter wbaxter at gmail.com
Mon Mar 30 16:18:14 PDT 2009


On Tue, Mar 31, 2009 at 7:37 AM, Christopher Wright <dhasenan at gmail.com> wrote:
> grauzone wrote:
>>
>> Christopher Wright wrote:
>>>
>>> grauzone wrote:
>>>>
>>>> Jarrett Billingsley wrote:
>>>>>
>>>>> On Sun, Mar 29, 2009 at 4:42 PM, Leandro Lucarella <llucax at gmail.com>
>>>>> wrote:
>>>>>>
>>>>>> This was discussed several times in the past. For example:
>>>>>>
>>>>>> http://www.digitalmars.com/d/archives/digitalmars/D/learn/weak_references_13301.html
>>>>>>
>>>>>> http://www.digitalmars.com/d/archives/digitalmars/D/learn/Soft_weak_references_8264.html
>>>>>>
>>>>>> http://www.digitalmars.com/d/archives/digitalmars/D/announce/ANN_WeakObjectReference_-_class_to_hold_weak_references_9103.html
>>>>>> etc.
>>>>>>
>>>>>> I hope it helps.
>>>>>
>>>>> The one provided by Bill:
>>>>>
>>>>> http://www.dsource.org/projects/scrapple/browser/trunk/weakref
>>>>>
>>>>> seems to work fine, and has the advantage of working in both Phobos and
>>>>> Tango.
>>>>
>>>> First, I doubt this actually works. The WeakRef stores the pointer as
>>>> size_t, but the GC is conservative and will still recognize the size_t as a
>>>> pointer. The unittest in the existing code only works, because he uses an
>>>> explicit delete on the referenced object.
>>>
>>> If the WeakRef is on the stack, this is true.
>>>
>>> If the WeakRef is part of an aggregate type that contains pointers, this
>>> is true.
>>
>> If WeakRef is a class, this is also true. Because all objects contain a
>> hidden monitor pointer, and the monitor is subject to garbage collection
>> AFAIK.
>>
>>> Otherwise, the GC will see that the relevant block is marked as having no
>>> pointers.
>>>
>>> True -- weakref is a difficult thing to make thread-safe.
>>
>> It seems there's still work to do, and a thread-safe WeakRef can't be
>> created with the current interfaces. Is this true?
>>
>> I'm thinking rt_attachDisposeEvent() should take a *pointer* to the
>> reference instead of the reference itself (effectively a double pointer),
>> and clear this pointer during garbage collection, when all threads are still
>> globally locked.
>
> Hold on, I think this isn't a real issue.
>
> You have essentially:
> class WeakRef
> {
>        const xor = 0x101010101;
>        size_t value;
>        bool collected;
>        Object toObject()
>        {
>                if (collected) return null;
>                auto ptr = cast(void*)(value ^ xor);
>                auto obj = *cast(Object*)&ptr;
>                if (collected) return null;
>                return obj;
>        }
> }
>
>
> After casting, you have a strong reference to the object, so it's impossible
> for the object to be collected if it hasn't yet been collected. If the
> object was collected between the two checks, you just have an invalid object
> reference that nobody ever uses. As long as the compiler doesn't do nasty
> reordering things, you should be fine.

Pardon my ignorance, but how do you know that ptr ^ xor is not a
pointer to some other real object in memory?   Does the language give
you some guarantee that it won't ever be a valid pointer?

--bb



More information about the Digitalmars-d mailing list