Hi,
I found a bug recently which has the following symptoms:
- If you remove a class from the system, which is referenced from a
method, then the method will keep a reference for the class, but the
class will be obsolete.
- If you create a class with the same name, then the old references will
still point to the old, obsolete class instead of the new one.
So there will be two bindings in the system using the same class name, but
pointing to different classes.
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.
2) Create a new object (a datastructure) which points to the binding
weakly and provides fast lookup by class name. Store the binding in this
object when the class is removed and when a class is added, then check
this object for existing bindings (besides Undeclared). This solution is
fast, but more complicated than the previous one. But the same kind of
datastructure can be used to replace Undeclared, so it will not hold onto
bindings unnecessarily and it won't have to be cleared manually.
I uploaded a few days ago System-ul.497.mcz to the Inbox which provides
solution #1. There are ways to improve the performance of SystemNavigation
>> #allCallsOn: by ~20%, so it will take only 20-40ms more to remove a
class from the system, which might be good enough for now.
In 4.5 I'd like to implement solution #2 and replace Undeclared to work
this way too, but I think for 4.4 we can live with solution #1. What do
you think?
Cheers,
Levente