<<

$: An Optimizing for

Ralph E. Johnson Justin 0. Graver Lawrence W. Zurawski

Department of Computer Science University of Illinois, Urbana-Champaign

Abstract compiler for Smalltalk that results in a large speedup over interpreters. The performance of TS indicates TS (Typed Smalltalk) is a portable optimizing com- that the real reason that Smalltalk is inefficient is piler that produces native for a typed information-hiding provided by object-oriented pro- variant of Smalltalk, making Smalltalk programs gramming. much faster. This paper describes the structure of Most attempts to speed-up Smalltalk have focused TS, the kinds of optimizations that it performs, the on optimizing the instead of building an constraints that it places upon Smalltalk, the con- . The reason is easy to see. In the straints placed upon it by an interactive programming absence of type information, a compiler cannot de- environment, and its performance. termine which method (procedure) is being invoked by a message send (procedure call). Since control 1 Introduction structures, field selection, arithmetic operations, and array accesses are all accomplished by sending mes- A number of recent Smalltalk implementations have sages, the compiler has virtually no information on acceptable performance[DS83][CW86][SIJII86]. This which to make optimizations. has been achieved as much by the increase in proces- The importance of a is illustrated sor speed as by improvements in software technology. by two that compile subsets of Smalltalk However, all current implementations of Smalltalk to efficient machine code: Hurricane[Atk86] and are slower than those of languages like . Smalltalk’s Quicktalk[BMW86]. Both compilers use a type sys- poor performance is usually ascribed to late-binding tem to determine the methods that would be invoked of procedure calls, heavy use of closures, and dy- by a particular message send. Quicktalk produces the namic memory management. However, Smalltalk im- fastest code but has the most restrictive type system. plementations such as PS and SOAR reduce the cost Quicktalk produces speed-ups of over 20 using only of these language features. SOAR spends two-thirds modest optimizations, but few large Smalltalk meth- of its time executing primitives. Thus, even if proce- ods satisfy the restrictions of the compiler. While dure calling and memory management were neither Quicktalk nor Hurricane accept full Smalltalk, completely removed, SOAR could be no more than a they show the potential for code optimization to im- third faster. TS (Typed Smalltalk) is an optimizing prove the speed of Smalltalk.

Authors’ address: Department of Computer Science, 1304 The type system of TS[Joh86][JG87] is more pow- West Springfield Ave., Urbana IL 61601 erful than the type systems of Hurricane or Quick- Telephone: (217) 244-0093 talk. It type-checks most large Smalltalk methods, E-mail: fiohnson,graver,mrawski}Qcs.uiuc.edu ensures that each variable always contains an object whose class is compatible with the type of the vari-

Permission to copy without fee all or part of this material is granted provided able, and allows the type of a variable or expression tha1 the copies are not made or distributed for direct commercial advantage. to be expressed precisely enough that the compiler the ACM copyright nowe and rhe title ofthe publication and its date appear. can deduce the set of methods that can be invoked and nolice IS given that copying is by permission of the Association for Machinery. To copy otherwise, or to republish. requires a fee and/ by a particular message. Neither of the earlier type or specific permission. systems is sufficient for type-checking all Smalltalk methods, and neither ensures that the contents of 0 1988 ACM O-89791-284-5/88/0009/0018 $1.50 a variable is always an object in a particular set of

18 OOPSLA‘88 Proceedings September2540,lw classes. Quicktalk treats compiled methods as “user l beta reduction, i.e. elimination of creation primitives”, and if the classes of the arguments dif- and evaluation. fer from their types then the primitives fail, just like These are only a small fraction of the optimizations normal Smalltalk primitives. Hurricane treats types that are potentially useful. However, they are sufi- as hints to the compiler, and produces code to han- cient to provide a dramatic performance increase. dle the cases where the classes of objects are different TS converts’ optimized parse trees into programs than what was expected. written in a machine-independent register transfer TS uses a set of very general optimizations, most language, which is also used to write Smalltalk prim- notably early binding of procedure calls (message itives. This increases portability and is useful for sends) and in-line substitution of calls to user-defined optimizations because it allows uniform in-line sub- and primitive methods. The result is that Smalltalk stitution of primitives and of methods written in programs are converted into a form similar to C or Smalltalk. The code generation algorithm performs Pascal programs, permitting standard code optimiza- several optimizations on the register transfer instruc- tion techniques to be used. TS has been designed so tions, often eliminating entire uses of the primitives. that it can be easily ported to any machine with 32 A single representation for code simplifies the com- bit integers and pointers. It currently runs on a Tek- piler, as well. tronix 4405 and produces Motorola 68020 machine The code generator is modeled after PO, by David- language. son and Fraser[DFSO]. PO takes a stream of instructions, converts each instruction into a sequence of register transfer instructions, optimizes 2 An Overview of TS the resultirlg sequence, and then converts it back to assembly language. The main optimization is com- TS reuses many of the components of the Smalltalk- mon subexpression elimination. The conversion back 80 programming environment, including most of the to assembly language selects the best instruction for a original compiler. The reused classes served as an sequence of register transfer instructions. The result interface between the various people working on the is that is performed automat- project. This reuse of code and interfaces let six inex- ically by a machine independent algorithm. perienced Smalltalk build the compiler We modified the algorithm of PO slightly[Wie87]. in a relatively short time. Assembly language is never generated. Instead, parse The standard Smalltalk parser produces a parse trees are converted directly to register transfer in- tree consisting of instances of subclasses of ParseNode. structions. Register transfer instructions are also We changed the parser to allow the types of variables used to describe the Smalltalk primitives, which are to be declared. Since the Smalltalk- compiler uses usually written in native machine language and em- a recursive descent parser, it was easy to build the the bedded in the interpreter[GR83]. In TS, a primitive parser for TS ‘by subclassing the Smalltalk- Parser method is defined using the register transfer language, class. and can be read and written from the browser. Thus, A TS parse tree can type-check itself, resulting in there are no black-box primitives in TS; all code can a parse tree decorated with type information[Gra86]. be inspected by the . Of course, a pro- In particular, each parse-node representing a message grammer must know the register transfer language for send knows the type of the receiver. There are many this to be useful. different kinds of types, and some of them specify a A message send can be implemented in one of three set of classes. ways. The most efficient is in-line substitution. This Once a parse tree is type-checked, the type can only be done when the class (or set of potential information can be used to perform high-level classes) of the receiver is known and should only be optimizations[Loy88]. The ones that are currently done when the method being invoked is small. If the implemented are: class of the receiver is known but the method being invoked is large then a message send is implemented l conversion of a message send into a case state- as a procedure call using native machine instructions. ment with procedure calls (when the receiver is Finally, if the class of the receiver is not known, in- known to be in a small set of classes), line caching[DS83] is used for method-lookup. In- * line caching is implemented by procedure calls. Thus, l in-line substitution of procedure calls, there is no need for a “method lookup” primitive in - the code generator, though there is a routine in the l tail recursion elimination, and in-line caching system for that purpose.

September 2530,1988 OOPSLA‘88 Proceedings 19 All knowledge about run-time structures is isolated neither of the two object types in the second type are to the translation from parse trees to register transfer equal to the object type in the first. Although these instructions. In particular, the from reg- types seem similar, they are completely different. An ister transfer instructions to native machine instruc- object of type Array of: Character is not of type Ar- tions knows nothing about method-lookup or the for- ray ofi (Integer + Character) since it cannot have an mat of method contexts. This probably makes the integer stored in it. A variable of type Array of (Inte- compiler less portable, since it means that primitives ger + Character) is not of type (Array of: Integer) + need to know the exact format of objects, whether (Array of: Character) because it cannot be assigned the stack grows up or down, and where to find ar- something of type (Array of: Integer). guments. This problem has been partly overcome by adding macros to the register transfer language for 3.1 Type Declarations accessing method arguments and returning results. We plan to try porting our compiler to another plat- As our examples of types illustrate, a class may be re- form soon; this will undoubtedly reveal many more garded as having certain type parameters. The list of machine dependencies. types that an object type associates with a given class name C will contain one type for each type parameter of class C. These type parameters are declared when 3 Types the class is created, and can be referred to in the methods of the class as if they were types. The fol- Types in Typed Smalltalk are similar to sets of lowing class definition declares OrderedCollection to classes. To be precise: be a subclass of SequenceableCollection with a type parameter Elementnpe. An object type is a class name together with a possibly empty list of types. SequenceableCollection subclass: #OrderedCollection A type is a non-empty set of object types. instancevariables: ‘firstlndex (Smalllnteger) lastlndex (Smalllnteger)’ An object type describes the type of a single object. classVariables: ” The class name in the object type is the class of the typeparameters: ‘ElementType’ object, while the list of types describes the types of poolDictionaries: ” the components of the object. For example, the type category: ‘Sequenceable-Collections’ of an array whose elements are integers is Array oj Integer.’ Array is the class name and the list of types Note that the type of each instance variable is de- consists of the single type Integer. The type Integer clared when the variable is declared and that angle is a single object type with a class name Integer and brackets are used to set off types from the regular an empty list of types. Smalltalk code. Type parameters like ElementType The type of a variable or expression describes the and cIasses like Smalllnteger can be used as types. objects that are possible values of ‘the variable or ex- Other classes, such as SequenceableCollection, return pression. An example is (Array of: Integer) + (Array types when sent the of: message, the ofiof: message, of: Character) + (Array oj (Integer + Character)). and so on. Here, the plus operator is read as ‘or’, so a variable The range of a type parameter may be restricted of the above type could contain an Array whose ele- by including an optional range declaration. The ments are all Integers, all Characters, or a mixture of range declaration of a type parameter is syntactically the two. identical to the type declaration for a variable. In One feature of this type system is that type inclu- the above example, if we wished to the ele- sion (i.e. type specificity) is exactly the same as the ments of the OrderedCollection to be characters, the subset relationship on the sets of object types mak- typeparameters: field would be declared as ‘Element- ing up a type. Thus, an object of type Integer is a Type (Character)‘. member of type Integer + Character. Class variables and instance variables have their This definition of type permits subtle distinctions types declared when their defining class is created. between types. Consider the two types Array of: (In- However, method arguments, temporary variables, teger + Character) and (Array of: Integer) + (Array and block arguments all have their types declared in of: Character). Neither is a subset of the other-the a method, as will be seen later. first has one object type and the second has two, but A signature type is a type (i.e. a set of object types)

‘Types will be in italics. Class names and Smalltalk code specified by a set of message types. A message type will be in a sans serif font. is the type of a message, not an object, so it is not

OOPSLA ‘88 Fbceedjngs sEplember25-30,1!398 really a type. It consists of the name of the message, nite union of object types contains a includes type, the type of the message’s arguments, and the type of while a signature type includes a type T if every mes- the value that the message returns. A object type T sage in the signature is type correct for each object is in the signature type if, for each message type m type in T. A message is type correct for a signature in the specification of the signature type, a message type if it matches the corresponding method in the of type m sent to an object of type T is type-correct. signature. A signature type can be thought to include object Type-checking is actually more complicated than types belonging to classes not yet created. Under this. TS uses case analysis to type-check some meth- this interpretation, signature types contain an infinite ods, and the programmer can use type-coercion when number of object types. In fact, the type specified necessary. Details can be found in [JG87]. by an empty signature contains every possible object type. Since signature types specify the largest possi- ble types, procedures that use them exhibit the most 4 A Simple Example polymorphism and so are the most flexible. However, We will illustrate the way the compiler works by use of signature types prevents the compiler from per- showing how the method for max: in class Magnitude forming some important kinds of optimizations, since is compiled. The code for this method is they do not provide enough information about the class of the receiver to allow compile-time binding of { arguments: aMagnitude (MagnitudeType) message sends. returnType: (Magnitudenpe))

max: aMagnitude 3.2 Type-checking 1 self < aMagnitude ifTrue: [aMagnitude] Type-checking infers the types of expressions and en- iffalse: [self] sures that each statement is type-correct. An assign- This is identical to the original Smalltalk- method ment statement is type-correct if the type of the ex- except for the type information prefix. pression on the right-hand side (viewed as a set of Method < in class Magnitude is known to return object. types) is a subset of the type of the variable an object of type l+ue + False (also called Boolean- on the left-hand side. A return statement is type- Type), but it is actually implemented by subclasses of correct if the type of its expression is a subset of the Magnitude, so its exact definition is not known. How- return type of the method. A statement sequence ever, the iffrue:ifFalse: message to its result can be is type-correct if each statement in the sequence is converted into a case statement with procedure calls, type-correct. as follows: 2 Due to the simplicity of Smalltalk, the only remain- t e self < aMagnitude. ing language construct is the message send. A mes- case sage send is type-correct if it is type-correct for each t = true possibIe class of the receiver. Let, method(C, msg) de- t fcall True::iffrue:ifFalse:([aMagnitude],[self]). note the method invoked when message msg is sent, to t = false an object in class C. The sending of msg to an object in class C is type-correct if the message type describ- + tcall False::iffrue:ifFalsc:([aMagnitude],[self]), ing the send includea the message type of method(C, Each of the two procedure calls can be replaced msg). This will be true if there exists an assignment by its definition. The ifTrue:ifFalse: message for of types to type parameters (type variables) such that class True evaluates its first argument, while the the type of each argument of the message send is a ifTrue:iffalse: message for class False evaluates its sec- subset of the type of the corresponding argument of ond argument. Thus, the result is the message type of method(C, msg). Finding this as- t t self < aMagnitude. signment requires unification. The return type of a case message send to an object in a particular object type t = true -+ t[aMagnitude] value. is the return type of the corresponding typed message t = false -+ T[selt] value. with each type parameter replaced by the type that was assigned to it in the previous matching. The re- Evaluating a constant block can be reduced at com- turn type of a message send is the union of the return pile time to the expression in the block, so the method types of the message sends for each component object will end up as: type of the receiver. ‘The notation here is not legal Smalhalk, but a printable Type-checking with signature types is easy. No fi- representation of the parse tree.

September2530,1988 OOPSLA ‘88 Proceedings t + self < aMagnitude. case { arguments: aNumber t = true + faMagnitude. returnType: ) t = false ---, Tself. < aNumber A particular use of max: is likely to be optimized by < primitive: 3 in-line substitution, providing further opportunities ‘dl +-SO. for optimization. For example, suppose x and y are d2 +Sl. declared to be of type SmallInteger. The expression z +(d2 & 16r80000000) = 0. “check class of arg.” x max: y would be converted into the expression -z 112 “fail if wrong.” dl cdl {1:31} *Convert self.” tcx ‘code’>, where n is the integer l2’> assigned to the primitive by Smalltalk-80, is Tsuper < aNumber the type of the object that the primitive returns if it succeeds3 and ‘code’ is the register transfer language program. Figure 1 shows the TS definition of the < Figure 1: Definition of primitive for Smalllntcger < method for Smalllntcgcr. The register transfer language uses the standard The register transfer program defining Smalllnteger Smalltalk- syntax for variables, constants, and bi- < (Figure 1) first fetches the receiver and operand nary operators. Variables come in four flavors: ad- from the stack and stores them in dl and d2. It then dress valued registers (al, a2, . . . ), integer valued tests to see if the second argument is a Smalllntcger. data registers (dl, d2, . . . ), byte valued data reg- As in other Smalltalk implementations, Smallintegers isters (bl, b2, . . .), and special registers like the are flagged by having certain bits set. In this case, stack pointer (SP), a register holding the constant nil the high-order bit of a Smalllnteger is 0. The operands (NIL), and the condition code registers. The only con- are then converted to the machine representation for stants are integers, though there are ways to access an integer and compared. The last half of the method global variables and other objects using the current returns a boolean object as a result. It depends on method’s literal frame. the fact that the objects nil, false, and true are located Expressions usually contain only one operator. next to each other, so the addresses of the last two These operators include the usual arithmetic and log- objects can be calculated from that of the first. This ical operators. The C dereference operator * is used fact, like the representation of small integers, is spe- to dereference a pointer. The instruction 1 L jumps cific to the Tektronix implementation of Smalltalk. to label L and the instruction L 1 L jumps to label When the parse tree for x max: y is converted into a L if the t bit is set, which normally means that the register transfer program, the primitive definition of previous operation resulted in a zero. < will be substituted in-line. The registers $0 and $1 The arguments to a method are given special in the primitive definition will be replaced by refer- names. Register $0 refers to the receiver. The n ences to the receiver and argument of the method, in arguments to a method are named $1 through $n. this case x and y. The resulting register transfer pro- Register $n + 1 refers to the result to be returned to gram will be optimized and converted into a machine the sender. Using these special names makes it easier language program similar to the one in Figure 2. for the compiler to substitute a primitive in-line. Note that the quality of the resulting code is pretty poor. In particular, there is no reason to generate a 3Primitives can fail if the types of their arguments are incorrect-the Smalltalk code in the method is then executed. true or false object and then discard it immediately

22 OOPSLA‘88 Proceedings September25-30,1938 thereafter. Also, the argument is declared to be a small integer, so the first test is unnecessary. There are many optimizations of this kind that are needed. In spite of lacking many optimizations, the resulting code is much faster than the best interpreters, as will be seen in the next section.

5 Performance Evaluation

A compiler needs to produce fast code and to produce it quickly. TS is currently speeding up small exam- ples by a factor of 5 to 10 over the interpreter, but 00 move .l . a5,aO it takes 15 to 30 seconds to compile them. Both of 02 move.1 ;receiver in d0 W),dO these figures are certain to improve. The previous ex- 04 move.1 (-8,a5),dl ;argument in dl ample shows that better optimizations should be able 08 move.1 dl,d2 to make the resulting code several times faster than OA and.1 # 16r80000000,d2 ;Test if SmallInteger. it is now. The code generator has several bottlenecks. 10 tst.1 d2 Rewriting them should make TS two or three times 12 bne 3A faster and compiling TS should then make it about 16 bfext d0(1:3I},dO as fast as the current Smalltalk- compiler. 1A bfext dl{l:31},dl The following benchmarks compare TS with Quick- 1E cmp.1 dI,dO talk. It is impossible to compare absolute times be- 20 bmi 32 ;test x

September 2530,1988 OOPSLA ‘88 Proceedings 23 the interpreter, with the greatest speedup occuring fast. Smalltalk programmers are used to the compiler with the fewest collisions in the hash table of the set. taking no more than a second or two per method. Sets and dictionaries are used a lot in Smalltalk, and Moreover, the compiler is used as a command inter- both are based on hashing. Thus, this example indi- preter. The compiler can be a fast command inter- cates that TS should be able to make large programs preter by having it do few optimizations. However, quite a bit faster. changing one method can cause an arbitrary num- ber of other methods to be recompiled, so even a fast compiler will take a long time in some cases. 6 Programming Environment We make changing a method fast by keeping an un- Concerns optimized version of every method that depends on some other method. If the dependent method is told Smallta.lk-80 provides an extremely attractive pro- that its optimizations are invalid then it will use the gramming environment [Go184]. The user can incre- unoptimized version of itself until it can be reopti- mentally construct and test a program, changing even mized. Instead of 0ptimizing.a method immediately, the classes that provide the programming environ- all optimization takes place in the background. Thus, ment. An optimized method has assumptions about when a method’s optimizations are invalidated, it will other methods encoded within it, so changes to the place itself on the optimizer’s queue. Invalidating a other methods can make the optimized method in- method is 10 to 100 times as fast as reoptimizing it, correct. Thus, optimization does not integrate easily so this technique greatly improves the response time into the kind of programming environment provided of the compiler.[Whi87] by Smalltalk-80. One of the problems with performing in-line substi- The most important optimization, in-line substitu- tution is that the compiler needs to be able to deter- tion, is also the optimization that causes the most mine which methods should be substituted. In gen- problems. If method A is substituted into method B eral, rarely executed methods do not need to be opti- then any change to A will require the recompilation mized at all. Short methods should usually be substi- of B. Thus, in-line substitution creates dependencies tuted in-line, while long methods should not be. We between methods. have not yet tried to automate the decision of which There are several ways to handle these dependen- methods shouId be called by in-line substitution and cies. One way is to keep track of the dependents which by a procedure call. Instead, the programmer of each method and to recompile a method’s depen- marks methods as substitutable or nonsubstitutabie, dents when it is changed. However, nearly every and the compiler follows the advice. method depends on some other method, so it will take a great deal of space to store all these depen- dencies. Most of the dependencies will be on stan- 7 Project Organization dard methods with little chance of changing, such as iffrue:ifFalse:. Therefore, this approach will waste a Proponents of object-oriented programming cIaim it lot of space storing dependency information that is greatly improves reuse of code, and decreases the never used. amount of time needed to develop software. This Another solution is that recompiling a method project is evidence in support of these claims. The causes all other methods to be checked to see whether compiler was written by six people. Although the they need to be recompiled. This will waste a lot of first code for the type system was written in Decem- time, since most methods being recompiled have no ber of 1985, most of the work on the compiler took dependents. place after September of 1986. Indeed, four people on Our solution is to have several kinds of methods. the project did not even know Smalltalk at the begin- A jized method is not expected to change, so no de- ning of September 1?86. Somewhere between 2 and pendency information is kept for it. Before it can be 3 man-years have been spent on this project, mostly changed it must be converted to a changeable method. by students who did not previously know Smalltalk Converting a fixed method to be changeable requires nor had done much work on compilers. scanning all other methods to see which depend on We were able to reuse most of the parser, most it. Converting a method from changeable to fixed of the parse-node class hierarchy, and the user inter- will delete the dependency information kept for it. face tools. This not only saved an enormous amount Thus, we can make recompilation fast and minimize of work, but provided a common framework for the the dependency information required. project. The reused components provided standard It is very important that the Smalltalk compiler be interfaces between the people working on the project.

24 OOPSLA ‘88 Proceedings September 2!5-30,1998 The project was divided into one person each working f’.. type system is a prerequisite for optimizing

0l.l Smalltalk. Fortunately, it is possible to design a type system for Smalltalk that is flexible enough to allow 0 the type system most Smalltalk programs to be type correct, yet re- strictive enough to allow the compiler to optimize the l integrating the type system into the compiler and programs. While it is not yet clear that all the advan- programming environment tages of the Smalltalk environment can be preserved, high level optimizations on parse trees it should be possible to make Smalltalk as fast as any other language. optimizing register transfer instructions and pro- ducing machine code Aiknowledgements maintaining dependencies The authors are grateful to Tektronix for the dona- building an interface to the . tion of equipment, financial support and advice, to AT&T for financial support under the Illinois Soft- The most important shared interface was that of the ware Engineering Program, to NSF for support under parse trees, which was reused from Smalltalk-80. The grant CCR-8715752, and to Joe Loyal& John Wie- type system was also an important shared interface. gand, and James Whitledge for doing much of the Although the type checking algorithms were reimple- programming. mented several times, the interface remained stable. The register transfer language was also an important interface, and changes to it caused other code to be References rewritten. Since many of the students taking part in the [Atk86] Robert G. Atkinson. Hurricane: an op- project are doing so as part of a M.S. program, there timizing compiler for Smalltalk. In Pro- is a lot of turnover of project members. In fact, three ceedings of 0 OPSL A ‘86, Object- Oriented of the original students have been replaced by three Programming Systems, Languages and Ap others. We have stressed clean, understandable de- plications, pages 151-166, November 1986. sign to minimize the difficulty of learning the system, printed as SIGPLAN Notices, 21(11). but a new generation of students quickly learns which [BMW861 Mark B. Ballard, David Maier, and Allen parts of the system are well designed and which need Wirfs-Brock. QUICKTALK: a Smalltalk- more work. 80 dialect for defining primitive methods. In Proceedings of OOPSLA ‘86, Object- 8 Further Plans Oriented Programming Systems, Lon- guagea and Applications, pages 140-150, Although the compiler is becoming more reliable, November 1986. printed as SIGPLAN No- it has not yet compiled the entire Smalltalk- im- tices, 21(11). age. We plan to do that and quit using the inter- preter. We are rewriting , adding [CWSS] Patrick J. Caudill and Allen Wirfs- support for foreign functions, making it possible to Brock. A third generation Smalltalk- provide specialized method look-up routines, and pro- 80 implementation. In Proceedings of viding support for compiling applications to run out- OOPSLA ‘86, Object-Oriented Program- side the Smalltalk programming environment. Long- ming Systems, Languages and Applica- range problems that are being investigated are that of tions, pages 119-130, November 1986. providing the usual Smalltalk for optimized printed as SIGPLAN Notices, 21(11). code, type inference, and allowing typed and untyped [DF60] Jack W. Davidson and Christopher W. code to coexist safely. Fraser. The design and application of The compiler only performs a few optimizations, so a retargetable peephole optimizer. ACM it is just a skeleton of an optimizing compiler. How- lhnsactions on Programming Languages ever, because it converts Smalltalk programs into an and Systems, 2(2):191-202, April 1980. intermediate form that is very similar to C or Pascal, it can be fleshed out to perform most standard opti- [DS83] L. Peter Deutsch and Allan M. Schiff- mizations. Smalltalk should eventually be as efficient man. Efficient implementation of the as other languages. Smalltalk- system. In Conference Record

September2530,1988 OOPSLA‘88 Proceedings of the Tenth Annual ACM Symposium on Principles of Programming Languages, pages 297-362,1983.

[Go1841 Adele Goldberg. Smalltalk-80: The Interactive Programming Environment. Addison-Wesley, Reading, Massachusetts, 1984.

[GR83] Adele Goldberg and David Robson. Smalltalk-80: The Language and its Im- plementa2ion. Addison-Wesley, Reading, Massachusetts, 1983.

[Gra86] Justin Graver. Adding Qpe Specijica- tion and We-Checking Capabilities to Smalltalk-80. Master’s thesis, University of Illinois at Urbana-Champaign, 1986.

[J G87] Ralph E. Johnson and Justin 0. Graver. A User’s Guide lo loped Smalltalk. Tech- nical Report, Department of Computer Science, University of IIIinois at Urbana- Champaign, 1304 West Springfield, Ur- bana, Illinois, 1987.

[Joh86] Ralph E. Johnson. Type-checking SmalItaIk. In Proceedings of OOPSLA ‘86, Object-Oriented Programming Syslems, Languages and Applicalions, pages 3X- 321, November 1986. printed as SIGPLAN Notices, 21(11).

Foy881 Joseph LoyaII. High-level zplimization in a !Qped Smalltalk Compiler. Master’s thesis, University of IlIinois at Urbana- Champaign, 1988.

pJH86] A. Dain Samples, David Ungar, and Paul Hilfinger . SOAR: Smalltalk with- out . In Proceedings of OOP- SLA ‘86, Object-Oriented Programming Systems, Languages and Applicalions, pages 107-118, November 1986. printed as SIGPLAN Notices, 21(11).

fWhi87] James Robert Whitledge. An Interface for an Optimizer in the Highly InZerac- tive Environment of Smalltalk. Master’s thesis, University of Illinois at Urbana- Champaign, 1987.

[Wie87] John David Wiegand. An Object-oriented Code Optimizer and Generator. Mm- ter’s thesis, University of Illinois, Urbana- Champaign, 1987.

OOPSLA‘88 Proceedings September25.30,1988