Class reshaping and GC in ClassBuilder

Andreas Raab andreas.raab at gmx.de
Wed Aug 17 07:54:10 UTC 2005


My (rather lengthy) comment in ClassBuilder>>update:to: not only 
explains why the GC is there but it also discusses some ideas of getting 
rid of it:

<quote>
		"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."
</quote>

Cheers,
   - Andreas

Daniel Vainsencher wrote:
> Hi everyone.
> 
> At the moment, loading Traits into the image takes a while, because it 
> adds an instance variable to Behavior. This means that it reshapes all 
> of the metaclasses in the system, and since the reshaping of each class 
> requires a GC, this is very slow.
> 
> Has anyone looked into any of the alternatives that don't require a GC 
> for class reshaping?
> 
> Daniel Vainsencher
> 
> 




More information about the Squeak-dev mailing list