Spoon progress 27 July 2006: shared variables (including
ducasse at iam.unibe.ch
Sun Jul 30 19:59:12 UTC 2006
I really like this kind of email.
It is always cool to get another look at what what you believe you
> Shared variables in Smalltalk are stored as associations; the key
> is a
> shared variable name, and the value is an object associated with that
> name. When the compiler compiles source for a method that refers to a
> shared variable's name, it attempts to find an appropriate
> shared-variable association for that name. It stores that
> association in
> the "literal frame" of the resulting compiled method (currently, a
> of the method's bytes after the header and before the instructions).
> There are instructions for pushing the value of a particular
> shared-variable association from a method's literal frame onto the
> (or "temporary frame") of a context running that method (see
> Interpreter>>pushLiteralVariableBytecode, the implementation of
> interpreter operations 16r40 to 16r5F).
> Traditionally, all of these shared-variables associations are
> stored in
> dictionaries that the compiler knows about. As far as the compiler is
> concerned, the outermost shared-variable scope is represented by the
> "system dictionary", a singleton instance of the SystemDictionary
> called "Smalltalk". (Just to review, note that the system
> dictionary has
> an association whose key is the symbol #Smalltalk and whose value
> is the
> system dictionary itself. This association is used in the compiler
> methods that make use of the system dictionary.)
> Most of the associations in the system dictionary refer to
> classes. The
> key of each such association indicates the name of the corresponding
> class as far as the compiler is concerned. Additionally, each class
> a "name" instance variable. That is, the name of each class is
> stored in
> two distinct places: in the system dictionary, and in the class
> In effect, the compiler's notion of a class' name and the class' own
> notion of its name are distinct (and possibly conflicting).
> I propose to make the compiler use the classes' notion of names
> directly, so that there is only one naming scheme, and that the
> themselves are responsible for it. To do this, instead of storing a
> class' name symbol in its "name" instance variable, we can just store
> the shared-variable association that the compiled methods use (and
> used to be in the system dictionary).
> When the compiler wants to find a class with some name in some
> source a
> human just wrote, it can search the class hierarchy from the root
> Object). As I discussed earlier here with Ralph Johnson, it's
> not as fast as a dictionary lookup, but it's acceptable (the compiler
> tends not to be a part of the system that needs every cycle
> squeezed out
> of it).
> If the compiler finds multiple classes with some name in source
> submitted for compilation, it can present other information about
> classes (e.g., class category or module) to the human, and ask for a
> choice. When already-compiled methods are transferred between systems,
> there is no ambiguity, since class names aren't used at all (see
> "another reminder about live behavior transfer" below).
> the root class
> As you might guess, this means that Spoon will not have multiple root
> classes. So far, all the non-primary root classes in Squeak were
> motivated by a desire to use method lookup failure for various
> "proxyish" features. I support such features in Spoon directly with
> interpreter (see for example, class "Other"), so it's not necessary to
> have more than one root class (it's also not necessary to have the
> "ProtoObject" class).
> As for how to access the root class, there are a couple of
> options. We
> could store the root class' shared-variable association directly in
> methods, or we could store the root class in the "special objects
> (it could take the system dictionary's place there, in fact).
> the special objects array
> This brings me to the special objects array. :) I've always found it
> odd that it's chock-full of well-known and relatively unchanging
> but it doesn't have its own class and protocol. I've never liked the
> name "special objects array" either; it seems too vague.
> I think the special objects array represents the grip that the
> interpreter has (and needs to have) on the object memory. So for Spoon
> I've created a class called "InterpreterGrip" whose sole instance is a
> collection of the objects that the interpreter knows about. I call
> of these objects a "grip point". There is protocol for accessing them
> (for example, a "rootClass" message). I find this more pleasant
> than the
> current scheme.
> other shared variables
> Anyway, back to the system dictionary. I addressed the associations
> there that refer to classes, but there are others. These are the other
> so-called "global" variables (like Display, the primary display) as
> as all the "shared pools" (like TextConstants and, strictly speaking,
> Undeclared). I think each global variable should be the responsibility
> of some class. So the primary display could be something you get by
> sending "primary" to DisplayScreen.
> Shared pools are dictionaries of shared-variable associations,
> to the system dictionary (in fact, I'd call the system dictionary just
> another shared pool). I know some think we should simply banish all
> shared pools, but I'll assume for the moment that we're keeping
> them. I
> find them useful, I just think some class should take
> responsibility for
> each one. I've added a "publishedPools" instance variable to Class,
> which stores all the shared pool dictionaries for which a class has
> responsibility (i.e., the class that introduced the pool into the
> system). I renamed the traditional "sharedPools" instance variable in
> Class to "receivedPools"; these are the pools that a class merely
> Finally, I renamed the "classPool" instance variable to
> "classVariablesPool", just to be clearer.
> When you want to use a shared pool, you access the pool by sending a
> message to the responsible class, rather than relying on its name
> a global variable.
> method references to "Smalltalk"
> So now we've got new homes for all the shared-variable associations
> which used to be reachable through the system dictionary. The other
> thing to do is refactor the methods which use the shared-variable
> association for the system dictionary itself (the methods which
> refer to
> "Smalltalk"). I'm working on this now. There are about a thousand of
> them in a "full" object memory, but for most of them it's clear which
> class should actually take responsibility. For example, there are
> several methods which (in my opinion) are rightly the
> responsibility of
> the Interpreter class (like the garbage collection messages). I've
> written some refactoring tools that automate a lot of this (e.g., a
> which replaces the push of one literal variable with another when
> followed by the sending of a particular message).
> another reminder about live behavior transfer
> Some of these decisions would be problematic if we were limited to
> using source code ("fileouts") to transfer behavior between systems.
> Since Spoon can transfer methods directly, without recompilation (or
> even source code) and without referring to shared-variable names at
> it works (see the MethodLiteralTransmissionMarker hierarchy for
> why do this now
> This work was always lurking in the future, but now the issue is
> by my work on Naiad (Spoon's module system). I'm making a module which
> reattaches the primary display (the system is initially headless), and
> that meant deciding how to access it. Since access is traditionally
> through a global variable (Display), the can of worms was opened. :)
> Again, thanks in advance for any feedback or questions. I'm usually
> around on the Squeak IRC channel from 1700 to 0500 GMT, and I read the
> squeak-dev and Spoon lists.
> thanks again,
> Craig Latta
> Spoon mailing list
> Spoon at lists.squeakfoundation.org
More information about the Spoon