[squeak-dev] ClassBuilder update:to: broken with Spur (Eliot ?)

Eliot Miranda eliot.miranda at gmail.com
Tue Feb 3 15:18:29 UTC 2015


Hi all,

    I had failed to include a key change to make this work:

On Feb 3, 2015, at 2:29 AM, Stéphane Rollandin <lecteur at zogotounga.net> wrote:

>> first I think I missed an essential modification.  Find attached the key
>> version of ClassDescription>>updateInstances:from:isMeta:.
> 
> That did the trick ! No errors anymore, thanks !
> 
> Stef

Eliot (phone)

On Feb 2, 2015, at 5:45 AM, Stéphane Rollandin <lecteur at zogotounga.net> wrote:

> Hello,
> 
> In order to load muO in the latest Spur image, I had to reintroduce the garbageCollect that has been deleted from method #update:to: in ClassBuilder.
> 
> There is a verbose discussion in both the previous and current implementations of this methods.
> 
> From nice 3/10/2013, we read (talking about the Smalltalk garbageCollect bit):
> 
>    "Warning: Read this before you even think about removing the GC. Yes, it slows us down. Quite heavily if you have a large image. However, there's no good and simple alternative here, since unfortunately, #become: does change class pointers. What happens is that after the above become all of the instances of the old class will have a class pointer identifying them as instances of newClass. If we get our hands on any of these instances we will break immediately since their expected instance layout (that of its class, e.g., newClass) will not match their actual instance layout (that of oldClass). And getting your hands on any of those instances is really simple - just reshaping one class two times in rapid succession will do it. Reflection techniques, interrupts, etc. will only add to this problem. In the case of Metaclass things get even worse since when we recompile the entire class hierarchy we will recompile both, Metaclass and its instances (and some of its instances will have the old and some the new layout).
> 
>        The only easy solution to this problem would be to 'fix up' the class pointers of the old instances to point to the old class (using primitiveChangeClassTo:). But this won't work either - as we do a one-way become we would have to search the entire object memory for the oldClass and couldn't even clearly identify it unless we give it some 'special token' which sounds quite error-prone. If you really need to get rid of the GC here are some alternatives:
> 
>        On the image level, one could create a copy of the oldClass before becoming it into the new class and, after becoming it, 'fix up' the old instances. That would certainly work but it sounds quite complex, as we need to make sure we're not breaking any of the superclass/subclass meta/non-meta class variants.
> 
>        Alternatively, fix up #becomeForward on the VM-level to 'dump the source objects' of #become. This would be quite doable (just 'convert' them into a well known special class such as bitmap) yet it has problems if (accidentally or not) one of the objects in #become: appears on 'both sides of the fence' (right now, this will work ... in a way ... even though the consequences are unclear).
> 
>        Another alternative is to provide a dedicated primitive for this (instead of using it implicitly in become) which would allow us to dump all the existing instances right here. This is equivalent to a more general primitiveChangeClassTo: and might be worthwhile but it would likely have to keep in mind the differences between bits and pointer thingies etc.
> 
>        Since all of the alternatives seem rather complex and magical compared to a straight-forward GC it seems best to stick with the GC solution for now. If someone has a real need to fix this problem, that person will likely be motivated enough to check out the alternatives. Personally I'd probably go for #1 (copy the old class and remap the instances to it) since it's a solution that could be easily reverted from within the image if there's any problem with it."
> 
> 
> In the current version we read:
> 
>    "eem 5/31/2014 07:22 At this point there used to be a garbage collect whose purpose was to ensure no old instances existed after the becomeForward:.  Without the GC it was possible to resurrect old instances using e.g. allInstancesDo:.  This was because the becomeForward: updated references from the old objects to new objects but didn't destroy the old objects. But as of late 2013/early 2014 becomeForward: has been modified to free all the old objects."
> 
> 
> This latest statement may not hold true, since I could not load muO due to "Metaclasses can only have one instance" errors (originating in ClassDescription>>#updateInstances:from:isMeta:.
> 
> 
> Stef
> 
> 


More information about the Squeak-dev mailing list