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