Performance of primitiveFailFor: and use of primFailCode

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
23 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Performance of primitiveFailFor: and use of primFailCode

Igor Stasenko

On 25 May 2011 02:40, Eliot Miranda <[hidden email]> wrote:

>
>
>
> On Tue, May 24, 2011 at 5:34 PM, Igor Stasenko <[hidden email]> wrote:
>>
>> On 25 May 2011 00:51, Craig Latta <[hidden email]> wrote:
>> >
>> >
>> > Hi Igor--
>> >
>> >> > ...now I'm looking forward to ephemeron conflicts. :)
>> >> >
>> >>
>> >> What conflicts?
>> >>
>> >> Please elaborate :)
>> >
>> >     Oh, none yet, I just suspect there will be some with the stuff I
>> > wrote to GC stale methods.
>>
>> Yes. This could be a problem. Consider a following:
>>
>> MyClass>>someMethod
>>  ^ #( 'abc' 'def' )
>>
>>
>> ephemeron := Ephemeron new
>>   key: self someMethod first
>>   value: somethingElse.
>>
>> So, we created an ephemeron, whose key are object which came from
>> method's literals. And even worse,
>> as it shown above, it could be not a direct literal, but nested object.
>>
>> Now, if you GC this stale #someMethod , it will apparently turn
>> ephemeron's value to be weakly referenced,
>> and its key will be lost and replaced by nil.
>
> Uh, no.  The ephemeron refers to the string 'abc' that happened to be referenced by the method.  But that string won't be garbage collected until there are no references to it in the system, including from the ephemeron.  i.e. the ephemeron will either need to nil its key or itself be collected before the 'abc' string can be collected.

No.
Ephemeron's key held weakly. Right?
So, if key points to that 'abc' , and the only strong reference to
'abc' is via such method,
then if you remove method from system, the ephemeron's key will be
replaced by nil .. and rest of logic which follows, but its not
interesting..

Because same will happen if you just use weak objects:

array := WeakArray with: (self someMethod first) "which answers a
literal from that method".

now, imagine that you want to temporarily unload such "stale" method
from memory, but make sure that system pretends that it is still in
memory (if it is intended),
and still reachable from roots, you have to do something to make sure
that weak ref, held by array are not gone.

So, if you can solve this problem for usual weak refs, then you solve
that for ephemerons too.

> There is no magic here with references to objects from methods.  In Smalltalk, methods are just objects.  [and in the Cog VM there is a little bit of chicanery to preserve the illusion that there are no machien code methods involved, but that's what it does; hide the machine code].
>

--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Performance of primitiveFailFor: and use of primFailCode

Eliot Miranda-2
 


On Tue, May 24, 2011 at 5:57 PM, Igor Stasenko <[hidden email]> wrote:

On 25 May 2011 02:40, Eliot Miranda <[hidden email]> wrote:
>
>
>
> On Tue, May 24, 2011 at 5:34 PM, Igor Stasenko <[hidden email]> wrote:
>>
>> On 25 May 2011 00:51, Craig Latta <[hidden email]> wrote:
>> >
>> >
>> > Hi Igor--
>> >
>> >> > ...now I'm looking forward to ephemeron conflicts. :)
>> >> >
>> >>
>> >> What conflicts?
>> >>
>> >> Please elaborate :)
>> >
>> >     Oh, none yet, I just suspect there will be some with the stuff I
>> > wrote to GC stale methods.
>>
>> Yes. This could be a problem. Consider a following:
>>
>> MyClass>>someMethod
>>  ^ #( 'abc' 'def' )
>>
>>
>> ephemeron := Ephemeron new
>>   key: self someMethod first
>>   value: somethingElse.
>>
>> So, we created an ephemeron, whose key are object which came from
>> method's literals. And even worse,
>> as it shown above, it could be not a direct literal, but nested object.
>>
>> Now, if you GC this stale #someMethod , it will apparently turn
>> ephemeron's value to be weakly referenced,
>> and its key will be lost and replaced by nil.
>
> Uh, no.  The ephemeron refers to the string 'abc' that happened to be referenced by the method.  But that string won't be garbage collected until there are no references to it in the system, including from the ephemeron.  i.e. the ephemeron will either need to nil its key or itself be collected before the 'abc' string can be collected.

No.
Ephemeron's key held weakly. Right?

No.  An ephemeron refers to its key strongly, but it is notified when the only references to its key are from the keys of ephemerons.  The key of an ephemeron won't be collected unless the ephemeron nils its key on finalization, or removes itself from whereever it lived on finalization.

Ephemerons are *not the same* as weak references.  They are like guardians.  They are triggers that fire when the objects to which their keys refer are only reachable from their keys.  But they hold onto their keys (and all their other references) strongly.  Essentially they are used to detect when they are the last reference to some object.  But by holding onto that object they allow it to be finalized.

Take the classic case of finalization applied to, say, a file.  The issue is that we want the file's buffer to be flushed when it is finalized, not just the file descriptor to be closed.  If we use post-mortem finalization (where we finalize a surrogate object when we detect that the actual object has been GCed) then we have to duplicate the buffer update in the surrogate (we can share the buffer between the actual file and its surrogate, but we must update e.g. the file pointer into the buffer) and so do more work keeping the surrogate in sync with the actual file.  With ephemerons however, there is no need to use a surrogate; we use the actual object.  When its ephemeron detects (actually the GC detects, but its the ephemeron that gets notified) the file is unreachable it finalizes its file and removes itself from the ephemeron registry.  When the GC next runs the ephemeron is collected, and because the ephemeron is the only reference to the file, the file gets collected too.

This example also shows that for safe use of ephemerons one needs to run a full garbage collection and subsequent finalizations before quitting the system, to ensure that uses like the above get performed.

So, if key points to that 'abc' , and the only strong reference to
'abc' is via such method,
then if you remove method from system, the ephemeron's key will be
replaced by nil .. and rest of logic which follows, but its not
interesting..

No.  That's not correct.  See above. Ephemerons are /not/ like weak references.  They're related, but they don't behave at all the same.

HTH
Eliot
 

Because same will happen if you just use weak objects:

array := WeakArray with: (self someMethod first) "which answers a
literal from that method".

now, imagine that you want to temporarily unload such "stale" method
from memory, but make sure that system pretends that it is still in
memory (if it is intended),
and still reachable from roots, you have to do something to make sure
that weak ref, held by array are not gone.

So, if you can solve this problem for usual weak refs, then you solve
that for ephemerons too.

> There is no magic here with references to objects from methods.  In Smalltalk, methods are just objects.  [and in the Cog VM there is a little bit of chicanery to preserve the illusion that there are no machien code methods involved, but that's what it does; hide the machine code].
>

--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: Performance of primitiveFailFor: and use of primFailCode

Igor Stasenko

On 25 May 2011 03:12, Eliot Miranda <[hidden email]> wrote:

>
>
>
> On Tue, May 24, 2011 at 5:57 PM, Igor Stasenko <[hidden email]> wrote:
>>
>> On 25 May 2011 02:40, Eliot Miranda <[hidden email]> wrote:
>> >
>> >
>> >
>> > On Tue, May 24, 2011 at 5:34 PM, Igor Stasenko <[hidden email]> wrote:
>> >>
>> >> On 25 May 2011 00:51, Craig Latta <[hidden email]> wrote:
>> >> >
>> >> >
>> >> > Hi Igor--
>> >> >
>> >> >> > ...now I'm looking forward to ephemeron conflicts. :)
>> >> >> >
>> >> >>
>> >> >> What conflicts?
>> >> >>
>> >> >> Please elaborate :)
>> >> >
>> >> >     Oh, none yet, I just suspect there will be some with the stuff I
>> >> > wrote to GC stale methods.
>> >>
>> >> Yes. This could be a problem. Consider a following:
>> >>
>> >> MyClass>>someMethod
>> >>  ^ #( 'abc' 'def' )
>> >>
>> >>
>> >> ephemeron := Ephemeron new
>> >>   key: self someMethod first
>> >>   value: somethingElse.
>> >>
>> >> So, we created an ephemeron, whose key are object which came from
>> >> method's literals. And even worse,
>> >> as it shown above, it could be not a direct literal, but nested object.
>> >>
>> >> Now, if you GC this stale #someMethod , it will apparently turn
>> >> ephemeron's value to be weakly referenced,
>> >> and its key will be lost and replaced by nil.
>> >
>> > Uh, no.  The ephemeron refers to the string 'abc' that happened to be referenced by the method.  But that string won't be garbage collected until there are no references to it in the system, including from the ephemeron.  i.e. the ephemeron will either need to nil its key or itself be collected before the 'abc' string can be collected.
>>
>> No.
>> Ephemeron's key held weakly. Right?
>
> No.  An ephemeron refers to its key strongly, but it is notified when the only references to its key are from the keys of ephemerons.  The key of an ephemeron won't be collected unless the ephemeron nils its key on finalization, or removes itself from whereever it lived on finalization.

Ah. Ok. Then my implementation is not correct, since in it the key are
assumed to be held weakly.
It is strange that such detail slept through my mind unnoticed.
I will think what should be changed to correct that.

> Ephemerons are *not the same* as weak references.  They are like guardians.  They are triggers that fire when the objects to which their keys refer are only reachable from their keys.  But they hold onto their keys (and all their other references) strongly.  Essentially they are used to detect when they are the last reference to some object.  But by holding onto that object they allow it to be finalized.
> Take the classic case of finalization applied to, say, a file.  The issue is that we want the file's buffer to be flushed when it is finalized, not just the file descriptor to be closed.  If we use post-mortem finalization (where we finalize a surrogate object when we detect that the actual object has been GCed) then we have to duplicate the buffer update in the surrogate (we can share the buffer between the actual file and its surrogate, but we must update e.g. the file pointer into the buffer) and so do more work keeping the surrogate in sync with the actual file.  With ephemerons however, there is no need to use a surrogate; we use the actual object.  When its ephemeron detects (actually the GC detects, but its the ephemeron that gets notified) the file is unreachable it finalizes its file and removes itself from the ephemeron registry.  When the GC next runs the ephemeron is collected, and because the ephemeron is the only reference to the file, the file gets collected too.
> This example also shows that for safe use of ephemerons one needs to run a full garbage collection and subsequent finalizations before quitting the system, to ensure that uses like the above get performed.

I agree that detecting an "almost collectable" property is useful.
However it is certainly could be worked around. As Squeak history
shows
it is possible.


>>
>> So, if key points to that 'abc' , and the only strong reference to
>> 'abc' is via such method,
>> then if you remove method from system, the ephemeron's key will be
>> replaced by nil .. and rest of logic which follows, but its not
>> interesting..
>
> No.  That's not correct.  See above. Ephemerons are /not/ like weak references.  They're related, but they don't behave at all the same.
> HTH
> Eliot
>
>>
>> Because same will happen if you just use weak objects:
>>
>> array := WeakArray with: (self someMethod first) "which answers a
>> literal from that method".
>>
>> now, imagine that you want to temporarily unload such "stale" method
>> from memory, but make sure that system pretends that it is still in
>> memory (if it is intended),
>> and still reachable from roots, you have to do something to make sure
>> that weak ref, held by array are not gone.
>>
>> So, if you can solve this problem for usual weak refs, then you solve
>> that for ephemerons too.
>>
>> > There is no magic here with references to objects from methods.  In Smalltalk, methods are just objects.  [and in the Cog VM there is a little bit of chicanery to preserve the illusion that there are no machien code methods involved, but that's what it does; hide the machine code].
>> >
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>
>
>



--
Best regards,
Igor Stasenko AKA sig.
12