yet another smallest snapshot, and a visualization

Craig Latta craig at netjam.org
Sat Jan 21 01:01:04 UTC 2006


Hi Chris--

	The short answer is that you can leave out a lot of things when you 
know you're going to terminate within a few instructions. :)

 > My crude unerstanding of Spoon is that many other objects are
 > dynamically faulted into this tiny image at run-time (to do the 3+4),
 > is this right?

	This snapshot is not one that can grow into something more useful. It 
was just an experiment to see how small a snapshot I could make, with 
the new system tracer I wrote. I'm still working on a small growable 
system (currently 162k uncompressed), which does operate as you say (in 
addition to performing some other tricks).

	When you run the 1337 snapshot, the virtual machine gets the object 
address ("oop") for the special-objects array from the snapshot header 
(first 60 bytes). Indirectly from that array (through the Processor and 
its active process) it finds the active context and continues execution. 
The instructions executed come from a method used by the context. The 
instructions are: push (3), push (4), add, send (#quitPrimitive). The 
send invokes >>quitPrimitive, another method. That method terminates the 
virtual machine via a primitive. The virtual machine needs to look up 
 >>quitPrimitive in the method dictionary of the class of Smalltalk, a 
literal association in the literal frame of the initial context.

	In the above, we've touched the following objects from the snapshot 
file, in the following order:

1.	the special-objects array
2.	the global Processor association
3.	the Processor
4.	the active Process
5.	the active Process's suspended context
6.	the now-active context's method
7.	the symbol #quitPrimitive from the context's literal frame
8.	the global Smalltalk association
9.	the system dictionary (Smalltalk)
10.	class SystemDictionary
11.	SystemDictionary's method dictionary
12.	SystemDictionary's method dictionary's association array
13.	nil (touched during method lookup)
14.	that array's association for key #quitPrimitive
15.	the value for key #quitPrimitive (the second method)

	The method dictionary of the first method is in there also, as is true 
and false, making 18 objects. (The numbers 3 and 4 are immediates in the 
first method's literal frame.) I could kill those last three, but I 
declared victory when I got the thing under 1,337 bytes. :)

	I did all this using a system tracer implemented as a specialization of 
the virtual machine simulator. It's a simulator which keeps track of 
every object it touches as it runs. At any point, you can stop it and 
investigate the touched objects (read descriptions, follow pointers, 
etc.). Their cached oops are properly remapped during garbage 
collections. I used this information to guide a final garbage collection 
with extremely aggressive mark phase (basically, only mark the touched 
objects, and don't trace them), then just wrote a snapshot normally.

	So...

 > To do 3+4, you have to send a message (#+)...

	No, it has its own instruction ("bytecode").

 > ...to an instance of SmallInteger (ok, maybe just the immediate
 > object?).

	Right, small integers are immediate.

 > Still, you have two CompiledMethods in there, so you have
 > CompiledMethod class (but obviously not all of its superclasses).
 > Classes have a lot of information, how can all this fit into 18
 > objects?

	As you can see (hopefully) from the above, the only class we need is 
the one for the method for the single message-send we're doing 
(>>quitPrimitive). And the only one of its fields we need is the one for 
its method dictionary.

 > So are you able to measure how many objects are faulted [into the
 > growable sytsem] at run-time?

	Yes. :)

 > I just want to learn, thanks...

	Thanks for asking! It was good to write this down.


-C

-- 
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]





More information about the Squeak-dev mailing list