10/22/08 History • Prototype-based pure object-oriented language. Self • Designed by Randall Smith (Xerox PARC) and David Ungar (Stanford University). – Successor to Smalltalk-80. – “Self: The power of simplicity” appeared at OOPSLA ‘87. Kathleen Fisher – Initial implementation done at Stanford; then project shifted to Sun Microsystems Labs. – Vehicle for implementation research. • Self 4.2 available from Sun web site: http://research.sun.com/self/ Design Goals How successful? • Self is a very well-designed language. • Occam’s Razor: Conceptual economy • Few users: not a popular success – Everything is an object. – Everything done using messages. – Not clear why. – No classes • However, many research innovations – No variables – Very simple computational model. • Concreteness – Enormous advances in compilation techniques. – Objects should seem “real.” – Influenced the design of Java compilers. – GUI to manipulate objects directly Language Overview Objects and Slots • Dynamically typed. Object consists of named slots. • Everything is an object. – Data • Such slots return contents upon evaluation; so act • All computation via message passing. like variables • Creation and initialization done by copying – Assignment example object. • Set the value of • Operations on objects: associated slot – Method – send messages • Slot contains Self code – add new slots – Parent – replace old slots • References existing object to inherit slots – remove slots 1
10/22/08 Messages and Methods Messages and Methods • When message is sent, obj x 3 clone … clone … object searched for slot with name. obj print print point object • If none found, all parents are parent* parent* searched. print … print … – Runtime error if more than one obj x: 4 obj parent has a slot with the after setting same name. x to 4. • If slot is found, its contents parent* parent* evaluated and returned. x 3 x 3 – Runtime error if no slot found. x: ← x: ← Mixing State and Behavior Object Creation • To create an object, parent* … we copy an old one. + add points • We can add new methods, override parent* parent* existing ones, or even remove methods. x 4 x random number y 17 • These operations also apply to parent slots. generator x: ← y o y: ← y: ← Changing Parent Pointers Changing Parent Pointers frog jump … prince dance … frog jump … prince dance … eatFly … eatCake … eatFly … eatCake … p parent* p parent* parent*: ← parent*: ← p jump. p jump. name Charles name Charles p eatFly. p eatFly. p parent: prince. p parent: prince. name: ← name: ← p dance. p dance 2
10/22/08 Disadvantages of classes? Contrast with C++ • Classes require programmers to understand a • C++ more complex model. – Restricts expressiveness to ensure efficient – To make a new kind of object, we have to create a implementation. new class first. • Self – To change an object, we have to change the class. – Infinite meta-class regression. – Provides unbreakable high-level model of • But: Does Self require programmer to reinvent underlying machine. structure? – Compiler does fancy optimizations to obtain – Common to structure Self programs with traits : acceptable performance. objects that simply collect behavior for sharing. Implementation Challenges I Implementation Challenges II • Many, many slow function calls: • No static type system – Function calls generally somewhat expensive. – Each reference could point to any object, – Dynamic dispatch makes message invocation even making it hard to find methods statically. slower than typical procedure calls. • No class structure to enforce sharing – OO programs tend to have lots of small methods. – Everything is a message: even variable access! – Each object having a copy of its methods leads to space overheads. “The resulting call density of pure object- oriented programs is staggering, and brings Optimized Smalltalk-80 roughly 10 naïve implementations to their knees” [Chambers & Ungar, PLDI 89] times slower than optimized C. Avoid per object data Optimization Strategies Clone Families Model Implementation • Avoid per object space requirements. prototype Mutable • Compile, don’t interpret. map Fixed Info • Avoid method lookup. Fixed • Inline methods wherever possible. clone family – Saves method call overhead. Mutable – Enables further optimizations. Mutable Mutable Mutable Mutable Mutable Mutable Mutable Map Map Map Fixed Map Fixed Fixed Fixed 3
10/22/08 Avoid interpreting Avoid method lookup Dynamic Compilation Lookup Cache • Cache of recently used methods, indexed Source Byte Code Machine Code by (receiver type, message name) pairs. LOAD R0 01001010 MOV R1 2 01001100 • When a message is sent, compiler first ADD R1 R2 01001011 First … 01000110 Method consults cache method is entered – if found: invokes associated code. execution – if absent: performs general lookup and • Method is converted to byte codes when entered. potentially updates cache. • Compiled to machine code when first executed. • Berkeley Smalltalk would have been 37% • Code stored in cache slower without this optimization. • if cache fills, previously compiled method flushed. • Requires entire source (byte) code to be available. Avoid method lookup Avoid method lookup Static Type Prediction Inline Caches • Compiler predicts types that are unknown • First message send from a call site : but likely: – general lookup routine invoked – Arithmetic operations (+, -, <, etc .) have small – call site back-patched integers as their receivers 95% of time in • is previous method still correct? Smalltalk-80. – yes: invoke code directly – no: proceed with general lookup & backpatch – ifTrue had Boolean receiver 100% of the time. • Successful about 95% of the time • Compiler inlines code (and test to confirm • All compiled implementations of Smalltalk guess): and Self use inline caches. if type = smallInt jump to method_smallInt call general_lookup Avoid method lookup Inline methods Polymorphic Inline Caches Customized Compilation • Typical call site has <10 distinct receiver types. • Compile several copies of each method, – So often can cache all receivers. one for each receiver type. • At each call site, for each new receiver, extend • Within each copy: patch code: – Compiler knows the type of self if type = rectangle jump to method_rect – Calls through self can be statically selected if type = circle jump to method_circle and inlined. call general_lookup • Enables downstream optimizations. • After some threshold, revert to simple inline • Increases code size. cache (megamorphic site). • Order clauses by frequency. • Inline short methods into PIC code. 4
10/22/08 Inline methods Inline methods Type Analysis Message Splitting • Constructed by compiler by flow analysis. • Type information above a • Type: set of possible maps for object. merge point is often better. – Singleton: know map statically • Move message send “before” – Union/Merge: know expression has one of a fixed collection of maps. merge point: – Unknown: know nothing about expression. – duplicates code • If singleton, we can inline method. – improves type information • If type is small, we can insert type test and – allows more inlining crate branch for each possible receiver (type casing). Inline methods PICS as Type Source Performance Improvements • Polymorphic inline caches build a call-site • Initial version of Self was 4-5 times slower specific type database as the program runs . than optimized C. • Compiler can use this runtime information • Adding type analysis and message rather than the result of a static flow analysis to build type cases. splitting got within a factor of 2 of • Must wait until PIC has collected information. optimized C. – When to recompile? • Replacing type analysis with PICS – What should be recompiled? improved performance by further 37%. • Initial fast compile yielding slow code; then dynamically recompile hotspots . Current Self compiler is within a factor of 2 of optimized C. Impact on Java Summary • “Power of simplicity” Sun cancels Self Self with Animorphics – Everything is an object: no classes, no variables. PICs Smalltalk – Provides high-level model that can’t be violated (even during debugging). Java becomes popular • Fancy optimizations recover reasonable performance. • Many techniques now used in Java compilers. Animorphics Java • Papers describing various optimization Java Hotspot Sun buys A.J. techniques available from Self web site. http://research.sun.com/self/ 5
Recommend
More recommend