[squeak-dev] ObjectFinalizerTests>>testFinalizationOfEquals

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

[squeak-dev] ObjectFinalizerTests>>testFinalizationOfEquals

NorbertHartl
While trying to fix some things in pharo I came across a test
I have some problems with understanding (by the way this test has
vanished in 3.10).

testFinalizationOfEquals
   "self debug: #testFinalizationOfEquals"
       
   | bag o |
   bag := IdentityBag new.
   1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend:
#remove: to: bag with: n].
   1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend:
#remove: to: bag with: n].
   o := nil. "<-- Hello Klaus :)"
   Smalltalk garbageCollect.
   self assert: [ bag isEmpty ].

My problem is that toFinalizeSend:to:with adds an Objectfinalizer
to the finalizationRegistry of the instance. But

Object>>finalizationRegistry
   "Answer the finalization registry associated with the receiver."
   ^WeakRegistry default

returns a global object which is WeakKeyDictionary. And

| d |
d := WeakKeyDictionary new.
d at: (1 asString copy) put: $a.
d at: (1 asString copy) put: $b.
d size

prints 1. To me that would exchange every entry from the first
run by the second run (because the objects are equal).

So I would assume that if there does not happen a run of the
garbagecollector between the two loops the objects of the first
loop should be still contained in the bag. But the test is named
finalizationOfEquals so I have to assume: self doesNotUnderstand

Can someone explain it to me, please?

Norbert



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] ObjectFinalizerTests>>testFinalizationOfEquals

Adrian Lienhard

On Jun 14, 2008, at 12:29 , Norbert Hartl wrote:

> While trying to fix some things in pharo I came across a test
> I have some problems with understanding (by the way this test has
> vanished in 3.10).
>
> testFinalizationOfEquals
>  "self debug: #testFinalizationOfEquals"
>
>  | bag o |
>  bag := IdentityBag new.
>  1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend:
> #remove: to: bag with: n].
>  1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend:
> #remove: to: bag with: n].
>  o := nil. "<-- Hello Klaus :)"
>  Smalltalk garbageCollect.
>  self assert: [ bag isEmpty ].

just for clarification, the original version of the test used *equal*  
values (as the test name suggests):

bag := IdentityBag new.
1 to: 5 do: [:n | o := n asString copy. bag add: n. o toFinalizeSend:  
#remove: to: bag with: n].
1 to: 5 do: [:n | o := n asString copy. bag add: n. o toFinalizeSend:  
#remove: to: bag with: n].
Smalltalk garbageCollect.
1 to: 5 do: [:n | self deny: (bag includes: n)]

I guess, this test has been added to point out that the finalization  
mechanism does not correctly work when used concurrently with objects  
that are equal. The finalization registry uses a WeakKeyDictionary,  
rather than a WeakIdentityKeyDictionary, as Norbert notes below, thats  
why...

What was the rationale to remove this test in 3.10? Is this an  
expected behavior?

Adrian

>
>
> My problem is that toFinalizeSend:to:with adds an Objectfinalizer
> to the finalizationRegistry of the instance. But
>
> Object>>finalizationRegistry
>  "Answer the finalization registry associated with the receiver."
>  ^WeakRegistry default
>
> returns a global object which is WeakKeyDictionary. And
>
> | d |
> d := WeakKeyDictionary new.
> d at: (1 asString copy) put: $a.
> d at: (1 asString copy) put: $b.
> d size
>
> prints 1. To me that would exchange every entry from the first
> run by the second run (because the objects are equal).
>
> So I would assume that if there does not happen a run of the
> garbagecollector between the two loops the objects of the first
> loop should be still contained in the bag. But the test is named
> finalizationOfEquals so I have to assume: self doesNotUnderstand
>
> Can someone explain it to me, please?
>
> Norbert
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] ObjectFinalizerTests>>testFinalizationOfEquals

NorbertHartl
On Sat, 2008-06-14 at 14:33 +0200, Adrian Lienhard wrote:

> On Jun 14, 2008, at 12:29 , Norbert Hartl wrote:
>
> > While trying to fix some things in pharo I came across a test
> > I have some problems with understanding (by the way this test has
> > vanished in 3.10).
> >
> > testFinalizationOfEquals
> >  "self debug: #testFinalizationOfEquals"
> >
> >  | bag o |
> >  bag := IdentityBag new.
> >  1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend:
> > #remove: to: bag with: n].
> >  1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend:
> > #remove: to: bag with: n].
> >  o := nil. "<-- Hello Klaus :)"
> >  Smalltalk garbageCollect.
> >  self assert: [ bag isEmpty ].
>
Ah, I didn't notice the change from string to object. Now I know why
the test is green :)

thanks,

Norbert

> just for clarification, the original version of the test used *equal*  
> values (as the test name suggests):
>
> bag := IdentityBag new.
> 1 to: 5 do: [:n | o := n asString copy. bag add: n. o toFinalizeSend:  
> #remove: to: bag with: n].
> 1 to: 5 do: [:n | o := n asString copy. bag add: n. o toFinalizeSend:  
> #remove: to: bag with: n].
> Smalltalk garbageCollect.
> 1 to: 5 do: [:n | self deny: (bag includes: n)]
>
> I guess, this test has been added to point out that the finalization  
> mechanism does not correctly work when used concurrently with objects  
> that are equal. The finalization registry uses a WeakKeyDictionary,  
> rather than a WeakIdentityKeyDictionary, as Norbert notes below, thats  
> why...
>
> What was the rationale to remove this test in 3.10? Is this an  
> expected behavior?
>
> Adrian
>
> >
> >
> > My problem is that toFinalizeSend:to:with adds an Objectfinalizer
> > to the finalizationRegistry of the instance. But
> >
> > Object>>finalizationRegistry
> >  "Answer the finalization registry associated with the receiver."
> >  ^WeakRegistry default
> >
> > returns a global object which is WeakKeyDictionary. And
> >
> > | d |
> > d := WeakKeyDictionary new.
> > d at: (1 asString copy) put: $a.
> > d at: (1 asString copy) put: $b.
> > d size
> >
> > prints 1. To me that would exchange every entry from the first
> > run by the second run (because the objects are equal).
> >
> > So I would assume that if there does not happen a run of the
> > garbagecollector between the two loops the objects of the first
> > loop should be still contained in the bag. But the test is named
> > finalizationOfEquals so I have to assume: self doesNotUnderstand
> >
> > Can someone explain it to me, please?
> >
> > Norbert
> >
> >
> >
>
>