3 new mac VMs + pending Mac VM... (Finalization bug identified)

John M McIntosh johnmci at smalltalkconsulting.com
Thu Oct 12 08:36:24 UTC 2000


>John,
>
>>  If for example in WeakRegistry>>finalizeValues where we are creating
>>  that finObjects collection, then we invoke finalizeValues on the
>>  WeakKeyDictionary, what protection do we have from the VM from
>>  nilling keys as part of a GC between the traversal of the
>>  WeakKeyDictionary hunting for nils, then part (B) destroying the nils
>>  as this seems tobe a two step process?
>
>Bummer. Now that is a good one. One that I don't have an answer for. I
>suppose it *is* possible that it happens. But it's easy enough to find out -
>just add
>
>WeakKeyDictionary>>finalizeValues: removed
>   | assoc |
>   1 to: array size do:[:i|
>     assoc _ array at: i.
>     (assoc notNil and:[assoc key == nil
>       and:[removed includes: assoc value]]) ifTrue:[
>         array at: i put: nil.
>         tally _ tally - 1]].
>   self rehash.
>
>And change the line in the WeakRegistry to pass along finiObjects. If that
>does the trick I owe you a beer (at OOPSLA).
>
>   - Andreas

Two beers...

I removed the rehash since it recreates the array, however in 
Dictionary>>noCheckAdd: I think there is an issue because anObject 
key could become nil as we enumerate over the array and we could 
overwrite another entry who's key has become nil.

I also added a WeakKeyDictionary>>removeKey:ifAbsent: to avoid doing 
the fixCollsionsFrom: call. Since mmm I'm not sure I  understand it, 
but when I removed it the number of missed destroys went down.

Now for my test case I finalized 678 Sockets and only missed 12. 
Which is way better than the original case where I had failure in the 
mid-teens for socket finalization. But I think that if the dictionary 
needs to grow here, then again gee we build a new array and do that 
noCheckAdd: in Dictionary again which doesn't consider that anObject 
key could become nil as we enumerate over the array. { I think one 
could fall back to using anObject value as the key if the key becomes 
nil, so lets try that...)

Ah, ok now I don't lose any destroys, and the support code says all 
the sockets have been destroyed. ... FIXED! However I did get 3 
double destroys, but I saw those earlier and we just ignore it, (Sigh 
why double destroy that shouldn't happen).

OK so the problem is that the finalization is fragile. Toss too many 
finalizations at once and you will loose them.. (In my test case I 
did 1080 finalizations in about 45 seconds)

So more critical is that we need to rethink how finalization gets 
done, since the key value nil is being used to indicate both 
finalization and a control for terminate/cleanup (historically for 
example noCheckAdd dates from 1996) within the Dictionary/Set 
hierarchy. This of course as you see causes problems.

Of course a quick trial with setting the finalized key to true shows 
while you need to visit everywhere where a WeakArray is being used to 
prevent disaster (like Symbol intern:) The thought here is to set the 
key to true, in the GC. Then examine it in Smalltalk and turn it to 
nil as we process, then cleanup the nil key values at some point.

Tomorrow after some reflection I'll tackle a change set.

PS Nasty little bug...
-- 
--
===========================================================================
John M. McIntosh <johnmci at smalltalkconsulting.com> 1-800-477-2659
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================
Custom Macintosh programming & various Smalltalk dialects
PGP Key: DSS/Diff/46FC3BE6
Fingerprint=B22F 7D67 92B7 5D52 72D7  E94A EE69 2D21 46FC 3BE6
===========================================================================





More information about the Squeak-dev mailing list