Hi,
Weak references can leave dangling pointers if the weak object is in old space and it points to a new space object.
Your observation troubles me greatly. This should not happen, and as far as I know it cannot happen. Do you have a reproducable example?
The problem occurs when the new space object is incrementally collected but the old space weak object remains. The weak object now has a dangling pointer to where the new space object was.
This must not happen. Never. Not once. When a weak object becomes old it will be marked as "root" and root objects are always traced as if they are non-weak (the reason being that treating them weak would have complicated GC logic more than I liked).
The way this works is subtle however: When GC kicks in we trace the roots via #markAndTrace: and here, we have basically the same logic as in startObj *except* that we set lastField regardless of whether the root is weak or not (and lastField ultimately determines whether the GC logic finds an object via reference). Therefore, if a weak object is a root, it will be traced as if non-weak. You can test this by doing something like:
weakRef := WeakValueAssociation new. Smalltalk garbageCollect. "make it old" weakRef value: Object new. Smalltalk garbageCollectMost. "incr. GC" weakRef value. "and it's still there"
As far as I can tell, your changes should have no effect whatsoever.
Troubled, - Andreas