Last updated at 2:08 pm UTC on 16 January 2006
From the class comment (version 3.3a-4769)
NOTE: The SystemTracer was invented by Ted Kaehler. It has gone through many variations. I have simplified it and adapted it to work with Squeak's limited Object hashing. It has written runnable Mac images on a Mac. Some changes may be needed for it to produce runnable images on a bigEndian machine. – Dan I. 9/29/97
The SystemTracer runs through the system tracing every accessible object, and writing a copy of each object onto a disk image. It does this carefully enough that the resulting clone can be started up and run, just like a snapshot. Great care must also be taken that the tracer never sees (due to clamping) any of the structures created dynamically while writing the clone. If this happens an infinite recursion can result.
The tracer has built-in support for clamping unwanted (or unneeded) objects out of the system. It also allows fundamental changes to, eg, object header format, compiledMethod format, number formats, etc. The current version is fairly simple, as it just copies what is already in the system. This version does, however, reassign object hashes in order to illustrate how one must remap all the hashed structures accordingly.
Squeak currently only has 12 bits of object hash. A normal dictionary, used to map from old oop to new oop, would bog down in a system of, say, 50k objects. This tracer has a special structure that is optimized for this purpose. See the comment in initOopMap. If we ever extend the object hash, this structure could be replaced by a simple IdentityDictionary.
When you first start up the cloned .changes file, you will probably get a "cannotReturn" error, a vestige of the old tracing process. This can simply be closed (or maybe you can figure out how to fix the tracers so it doens't happen ;-).
Further comment from Tim Rowledge's message about replacing classes...
The cloner already does a great job of allowing one to leave out classes,
individual instances, change representation of particular objects etc.
However, when doing the ncm stuff I needed a way to build the new class in
the image and test it before cloning. Thus at clone-time I needed to
a) replace each compiled method with a new compiled method
b) replace the class CompiledMethod with NewCompiledMethod
c) get rid of the now-redundant CompiledMethod class
Doing a) is easy, that is the stock in trade of the cloner.
Doing b) & c) is a little more complicated since I wanted to catch every
reference to CM and write it out as a reference to NCM and also needed to
To do this we need to make sure that when a ref to CompiledMethod is found we not only
write out the replacement reference to NewCompiledMethod (NCM) instead, but that we log both CM
and NCM as having been dealt with by putting _both_ into the oopmap with
the same new-oop. Thus when we find a reference to NCM (for example when
the subclass list of its superclass is scanned) it will already have been
'dealt with'. The system also has to cope with arbitrary order of finding
either of the involved objects; you cannot guarantee that one will be
spotted before the other and rely on that.
Take a look at SystemTracer>replace:withNew:class:length:trace:write: to
see the diferences from the normal #new:class:length:trace:write:. One also
needs to check Associations in order to 'correct' the value instvar if it
refers to a replaced class.