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
|