[net.lang.st80] HELP, Smalltalk problems

graver@uiucdcsb.CS.UIUC.EDU (06/26/86)

I am working with Ralph Johnson on building a type system for Smalltalk-80,
and we have run into some problems.  (By the way, we are running Smalltalk-80
on the Tektronix 4404.)  Most of the difficulties arise when we attempt to
add instance variables to classes with many instances (e.g. ClassDescription,
MethodDictionary, etc.).  In the case of ClassDescription, we tried to add
an instance variable which required that every class be recompiled.  When the
system was about half done with this recompiling we started getting "Low On
Memory" warnings.  Plodding on undaunted we eventually got thrown out of the
Smalltalk interpreter with the message: "Smalltalk system error - Too many
objects."  When we tried to add an instance variable to the class MethodDiction-
ary we encountered a quite different problem.  MethodDictionary was recompiled
with no problem, but then the "updateInstancesFrom: oldClass" message was sent
to the class description for the new class (MethodDictionary).  This involved
"recreating any existing instances of the argument, oldClass, as instances of
the receiver, which is a newly changed class."  The following message appears
in the method,

	oldClass allInstances do:
		[:old | ...
		old become: new]

The "allInstances" message yields a collection of all the MethodDictionaries
in the system.  These are then updated one at a time, as "new", and then the
object pointers are swapped with the "become:" message.  The problem occurred
when "become:" tried to swap the object pointers for the MethodDictionary that
contains the definition for the "become:" message.  We are thrown out of the
Smalltalk interpreter with the message: "Smalltalk system error - recursive
DoesNotUnderstand:."

We have a suspicion that the interpreter may assume certain things about some
fundamental classes and that adding instance variables as described above may
be impossible.  It would be helpful if someone could confirm or deny this.
We have also considered using the system tracer to modify such large classes,
but feel that this may be an unreasonable solution.  Has anyone ever used the
tracer for such a purpose and is it feasable?  Unless these problems can be
solved, our present solution is to change the meaning of existing instance
variables (for example, a list could easily become a list of ordered pairs or
ordered triples) or to build each "new" class from scratch.

Has anyone come across these problems before?  Has anyone found any solutions?
Does anyone have any suggestions?  I would appreciate any information that
anyone thinks would be helpful, thanks.


		Justin Graver

mdr@reed.UUCP (Mike Rutenberg) (07/02/86)

In article <9500001@uiucdcsb> graver@uiucdcsb.CS.UIUC.EDU writes:
>
>I am working with Ralph Johnson on building a type system for Smalltalk-80,
>and we have run into some problems.  (By the way, we are running Smalltalk-80
>on the Tektronix 4404.)  Most of the difficulties arise when we attempt to
>add instance variables to classes with many instances (e.g. ClassDescription,
>MethodDictionary, etc.).  In the case of ClassDescription, we tried to add
>an instance variable which required that every class be recompiled.  When the
 
I tried that once too, when I was working on my type system for
Hurricane, an optimizing compiler that I built.  To make an
understatement, adding an instance variable to something like
ClassDescription is very difficult.  Your image is probably
significantly different enough than the one that I have been using that
I couldn't tell you how to do it, but one will have to be very sneaky.
I eventually gave up and make a separate data structure, which in some
ways was a better idea, but I still would have liked to get that
"typeDelarations" variable in all the classes.

This was a long time ago (bout a year and a half) and I dare say if I gave
it a try again I could manage to pull it off.  It would probably involve
some very wierd putting the classes in wierd states as the update was going
on.  Poke around in the class creation messages and see exactly what
happens.

...
>ary we encountered a quite different problem.  MethodDictionary was recompiled
...
>
>	oldClass allInstances do:
>		[:old | ...
>		old become: new]
...
>object pointers are swapped with the "become:" message.  The problem occurred
>when "become:" tried to swap the object pointers for the MethodDictionary that
>contains the definition for the "become:" message.  We are thrown out of the
>
>We have a suspicion that the interpreter may assume certain things about some
>fundamental classes and that adding instance variables as described above may
>be impossible.  It would be helpful if someone could confirm or deny this.

Yes, I am sure that these classes are special. Some of them even have
known oops.  (See the blue book)  It is not impossible to do what you
wish to do, but I almost guarentee that the standard, existing every
day code will not work in this particular case.  You are really going
to have to get your hands dirty.

>We have also considered using the system tracer to modify such large classes,
>but feel that this may be an unreasonable solution.  Has anyone ever used the
>tracer for such a purpose and is it feasable?  Unless these problems can be

That is one of the main reasons that the SystemTracer was built in the
first place.  By all means, that is a possible solution, and probably
the easiest from your point of view.  I hope your tracer works:  I have
yet to see one that does, though I have been told that they exist :-).
Try to make a simple clone image first and find out.

>solved, our present solution is to change the meaning of existing instance
>variables (for example, a list could easily become a list of ordered pairs or
>ordered triples) or to build each "new" class from scratch.

This also might have some dangerous intermediate state conditions.  Be 
careful.

>Has anyone come across these problems before?  Has anyone found any solutions?

Most certainly. See above.

>		Justin Graver

	-bob atkinson
	BAtkinson.pa@Xerox.com
	BAtkinson.pa%xerox.com@csnet-relay.csnet
		or something like that. Get to the arpanet
		and you'll be fine.

brianw@tekcrl.UUCP (Brian Wilkerson) (07/08/86)

Justin Graver wrote:

> We have a suspicion that the interpreter may assume certain things about some
> fundamental classes and that adding instance variables as described above may
> be impossible.  It would be helpful if someone could confirm or deny this.

Unfortunately, your suspicions are correct.  The interpreter does depend on
the format of certain  objects since they are  accessed by the  interpreter
directly.  The  classes MethodDictionary, Behavior  and CompiledMethod  are
examples of  these.   Interpreter accesses  to these  objects rely  on  the
position of instance variables within the  object, rather than the name  of
the variable.   This means that  new instance variables  can only be  added
after all instance variables (named or indexable) used by the interpreter.

I know of  no way  (in the  standard image)  to add  instance variables  to
MethodDictionary.  The interpreter always allocates memory for an object in
such a way that named instance variables come first (in the order declared,
starting with  class  Object and  ending  with  the class  of  the  object)
followed by  indexed  instance  variables.    Since  MethodDictionary  uses
indexed variables  to  store  the  key (method  selector),  and  since  the
interpreter must perform method look-up by name (selector), the interpreter
must know where the  indexed instance variables begin.   This prevents  the
addition of named  instance variables.   Subclassing MethodDictionary  will
not work either (for the  same reason).  It  will probably be necessary  to
store the information you hoped to store with the method dictionaries  with
the class instead.

For a more complete explanation  of how and why  these classes are used  by
the interpreter, and  an indication  of the  classes and  objects that  are
directly used  by  the interpreter,  see  section  four of  the  Blue  Book
("Smalltalk-80: The Language and Its Implementation", Adele Goldberg, David
Robson, Addison-Wesley, 1983, pp.541-688).

> We have also considered using the system tracer to modify such large classes,
> but feel that this may be an unreasonable solution.  Has anyone ever used the
> tracer for such a purpose and is it feasible?

The system tracer can be used for this purpose, but doing so may require  a
great deal of effort  on your part (depending  on the specific changes  you
try to make).  It has been successfully used here at Tektronix for  similar
types of changes.   The system tracer  should allow you  to get around  the
"Too many objects" error you encountered.

>                                                Unless these problems can be
> solved, our present solution is to change the meaning of existing instance
> variables (for example, a list could easily become a list of ordered pairs or
> ordered triples) or to build each "new" class from scratch.

Again, changing the meaning of instance variables in these special  classes
is dangerous, at best.   The interpreter not  only makes assumptions  about
the format of the instances of these classes, but may also make assumptions
about the type of values stored in those instance variables.  (For example,
when performing method  look-up, the interpreter  assumes the  'methodDict'
field in Behavior points to an instance of the class MethodDictionary.)

Brian Wilkerson
   brianw@tektronix.UUCP
   ..!tektronix!tekchips!brianw