[squeak-dev] References to a removed and reloaded class
Levente Uzonyi
leves at elte.hu
Fri Sep 21 05:32:14 UTC 2012
On Fri, 21 Sep 2012, Levente Uzonyi wrote:
> Thu, 20 Sep 2012, Eliot Miranda wrote:
>
>>
>>
>> On Thu, Sep 20, 2012 at 1:45 PM, Levente Uzonyi <leves at elte.hu> wrote:
>> On Thu, 20 Sep 2012, Colin Putney wrote:
>>
>> On Thu, Sep 20, 2012 at 11:28 AM, Levente Uzonyi
>> <leves at elte.hu> wrote:
>>
>> In order to fix this bug, I came up with two ideas:
>> 1) Recompile all methods which point to the old class
>> when the class is
>> removed. This helps, because the class will be undeclared
>> at that point, so
>> a new binding will be stored in Undeclared and the same
>> binding will be used
>> when the class is added again. The drawback of this
>> solution is that it only
>> fixes references in methods and it's slow, since it has
>> to scan all methods
>> in the system.
>>
>>
>> Couldn't we just move the existing binding to Undeclared? That
>> might
>> be unnecessary if there are no references, but I don't think it
>> would
>> hurt.
>>
>>
>> I tried that, but ran into another issue related to Undeclared. Class >>
>> #rename: checks if the new class name is included in Undeclared. And if it
>> is, it'll #inform: about it. The problem is that Undeclared holds a strong
>> reference to its bindings, so if we remove a class which has no references
>> and we move it to Undeclared, then it will linger there, until someone
>> calls #cleanOutUndeclared. This is the weakness I described in solution #2.
>>
>> To work around this we can remove the unreferenced keys from Undeclared in
>> Class >> #rename:, but it means, that all methods in the system will be
>> scanned for each renamed class.
>>
>>
>> That's a price well worth paying. Traversing the class hierarchy to fid
>> methods is quite quick (much faster than allInstances) and class rename is
>> rare (i.e. a devlopment time activity, not a typical runtime activity). So
>> IMO this
>> is the way to go.
>
> I guess I wasn't clear, because #allInstances is not used by the solution I
> suggested. It does two things:
> When a class is removed, then
> 1) traverse the class hierarchy and search for methods which refer to the
> binding
> 2) recompile the methods found in step 1
>
> The alternative is to - nil out the value of the binding and move it to
> Undeclared when the class is removed
There's a test which expects that a removed class's method's class is not
nil, so setting the value of the binding to nil doesn't work.
Levente
> - when Undeclared is accessed from Class >> #rename: (and who knows which
> other methods) remove the unreferenced keys from it by traversing the class
> hierarchy searching for methods that refer to the binding. If no such method
> was found then the binding is removed from Undeclared.
>
> The reason why I don't like the alternative is that we don't know if there
> are other methods which use Undeclared in a similar way and therefore must be
> rewritten. The only reason I know about Class >> #rename: is because a test
> was failing when I moved the binding to Undeclared. It might not be that hard
> to find the methods, but it's still extra work to be done. I'll check it out
> though, because class renaming is definitely more rare than class removal.
>
>
> Levente
More information about the Squeak-dev
mailing list
|