/
type prediction type prediction

type prediction - PDF document

alida-meadow
alida-meadow . @alida-meadow
Follow
375 views
Uploaded On 2016-03-19

type prediction - PPT Presentation

SELF 32 is a dynamicallytyped objectoriented language inspired by theSmalltalk801 language 12 Like Smalltalk SELF has no type declarationsallowing programmers to rapidly build and modify sys ID: 261799

SELF [32] dynamically-typed

Share:

Link:

Embed:

Download Presentation from below link

Download Pdf The PPT/PDF document "type prediction" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

type prediction SELF [32] is a dynamically-typed object-oriented language inspired by theSmalltalk-801 language [12]. Like Smalltalk, SELF has no type declarations,allowing programmers to rapidly build and modify systems without interferencefrom out-of-date type declarations. Also, SELF behavior, and inherits shared behavior from its parent objects. Also unlike Small-talk, S accesses state solely by sending messages; there is no special syntax foraccessing a variable or changing its value. These two features, combined withSELFÕs multiple inheritance rules, help keep programs concise, malleable, andreusable.In a straightforward implementation, SELFÕs prototype-based model wouldconsume much more storage space than other dynamically-typed object-orientedprogramming languages, and its reliance on message passing to access state wouldexact an even higher penalty in execution time. We have developed and imple-mented techniques that eliminate the space and time costs of these features. In addi-tion, we have implemented other optimizations that enable SELF to run twice asfast as the fastest Smalltalk system. These same techniques could improve imple-mentations of class-based object-oriented languages such as Smalltalk, Flavors[20], CLOS [3], C++ [27], Trellis/Owl [23], and Eiffel [19].This paper describes our implementation for SELF, which has been running forover a year. First we review SELFÕs object and execution model in section 2. Thenwe describe SELFÕs object storage system in section 3, introducing maps and segre-gation and presenting object formats. Section 4 explains our byte-coded represen-tation for source code. Section 5 reviews the compiler techniques, originallypublished in [6]. Section 6 explains how these optimizations can coexist with anexploratory programming environment that supports incremental recompilationand source-level debugging. Section 7 compares the performance of SELF to thefastest available Smalltalk system and an optimizing C compiler. It also proposesa new performance metric, MiMS, for object-oriented language implementations.We conclude with a discussion of open issues and future work. constant contains a method in a slot named value; this method is special in that whenit is invoked (by sending to the block), the method runs as a child of its lexi- 62CHAMBERS, UNGAR, AND LEE3.1MapsA naive implementation of SELFÕs prototype object model would waste space. IfSELF were based on classes, the class objects would contain the format (names andlocations of the instance variables), methods, and superclass information for alltheir instances; the instances would contain only the values of their instance vari-ables and a pointer to the shared class object. Since SELF uses the prototype model,each object must deÞne its own format, behavior, and inheritance, and presumablyan implementation would have to represent both the class-like format, method, andinheritance information and the instance-like state information in every SELFobject.Luckily, we can regain the storage efÞciency of classes even in SELFÕs prototypeobject model. Few SELF objects have totally unique format and behavior. Almostall objects are created by cloning some other object and then modifying the valuesof the assignable slots. Wholesale changes in the format or inheritance of an object,such as those induced by the programmer, can only be accomplished by invokingspecial primitives. We say that a prototype and the objects cloned from it, identicalin every way except for the values of their assignable slots, form a clone family.We have invented maps as an implementation technique to efÞciently representmembers of a clone family. In our SELF object storage system, objects are repre- parent slotand the offsets of the assignable xand y slots.7.5-24 entered into the system, generating SELF-level byte code 70CHAMBERS, UNGAR, AND LEEThe index for the opcodes is an index into the accompanying object array. The 5-bit offset allows the Þrst 32 message names and literals to be referred to directly;indices larger than 32 are constructed using extra INDEX-EXTENSION instruc- ELF language and thelack of elaborate space-saving encodings. Smalltalk-80 deÞnes a much larger set ofbyte codes [12], tuned to minimize space and maximize interpretation speed, andincludes byte codes to fetch and store local, instance, class, pool, and global vari-ables and shortcut byte codes for common-case operations such as loadingconstants like nil, true lates into special byte codes. When executed, these byte codes either directlyinvoke the corresponding integer primitive operation (if the receiver is an integer),or perform the message send (if the receiver isnÕt an integer).Although this special processing for common messages may signiÞcantlyimprove the performance of existing Smalltalk systems, especially interpretedones, they violate the extensible and ßexible spirit of Smalltalk:¥The source code for the hard-wired methods is relegated to documentation, andall changes to the hard-wired source code are ignored by the system. AnydeÞnitions of ifTrue:ifFalse:, whileTrue:, and . Like other dynamic compilationsystems, our SELF system waits until the min: method is Þ compiler to evaluate the expressionimin:j, where i contains an integer at run-time. Assuming this is the Þrst timemin: has been sent to an integer, our compiler will generate code for a version ofmin: that is customized for integer receivers. The compiler Þrst builds the internalßow graph pictured at the top of the next page (expensive operations are in bold customized for integers, the compiler canstatically look up the deÞnition of deÞned for integers:()This method simply calls the integer less-than primitive with a failure block(omitted here for brevity). The compiler inlines this method to get to the ßowgraph below:The overhead for sending the message has been eliminated, but calling a proce-dure to compare integers is still expensive. The next section explains how ourcompiler open-codes common primitive built-in operations to further increaseperformance.5.3Primitive InliningPrimitive inlining can be viewed as a simpler form of message inlining. Calls toprimitive operations are normally implemented using a simple procedure call to anexternal function in the virtual machine. However, like most other high-perfor-mance systems, including some Smalltalk systems [11, 12], our S bzeropush truecmp self, argbranch-less-thanpush [...]create-closuresend value 78CHAMBERS, UNGAR, AND LEENow the compiler can inline the deÞnition of ifTrue:False: for the trueobject:ifTrue: trueBlk False: falseBlk = ( trueBlk value ).and for the false object:ifTrue: trueBlk False: falseBlk = ( falseBlk value ).to get to the following ßow graph:The two value messages can be inlined, replaced by the bodies of the blocks.Since none of the receiver and arguments of the inlined ifTrue:False:messages need to be created at run-time any more, the compiler eliminates themfrom the control ßow graph, producing the ßow graph at the top of the next page.LetÕs assume that the failure block for integer comparisons is too complex toinline away. The compiler wonÕt inline the value message, and so the valuemessageÕs result type is unknown at compile-time. Thus the receiver type of the ifTrue:False: message (weÕlljust look at the remaining unoptimized branch):push [...]create-closuresend valuecmp #truebeqcmp #falsebeqpush [self]push [arg]create-closurecreate-closurepush [self]push [arg]create-closurecreate-closurepush [self]push [arg]create-closurecreate-closuresend ifTrue:False:send ifTrue:False:send rootintegerroot mapinteger traits maptruetrue map17integer mapmin:parentparent(map dependency)(map dependency)parent min: (and for any othercompiled methods that depend on the same changed information) willbe thrown away and recompiled when next needed.in case min: is addedin case parent change affectsmin: lookupin case ifTrue:False: is changedin case 86CHAMBERS, UNGAR, AND LEEstarted but not completed for any program counter address. The execution stackdisplayer uses this mapping information to Þnd the bottommost virtual stack framefor each physical stack frame to display the call stack whenever the program ishalted.We have not implemented the breakpointing facilities in our debugger yet; thecurrent ÒdebuggerÓ displays the virtual execution stack and immediately continuesexecution whenever the _DumpSelfStack primitive is called. However, ourmapping system is designed to support computing and setting breakpoints in antic-ipation of breakpointing and process control primitives. To set a breakpoint at aparticular source-level byte code, the debugger would Þnd all those programcounter addresses associated with the byte code and set breakpoints there. In caseswhere several byte codes map to the same program counter address, single steppingfrom one byte code to the next wouldnÕt actually cause any instructions to beexecuted; the debugger would pretend to execute instructions to preserve the illu- 88CHAMBERS, UNGAR, AND LEERaw Running TimesSmalltalkSELFSELF-OOC(real ms)(cpu ms)(cpu ms)(cpu ms)perm1559660420120towers2130900560190queens859520470100intmm1490970(970)160puzzle165105290(5290)770quick1239690610110 ow. The rest of the difference is probably caused bythe lack of type information, especially for arguments and assignable data slots. Weare remedying these deÞciencies to a large extent in the second-generation SELFsystem described in the next section.The previous tables show that the performance of object-oriented systems isimproving dramatically. As a new metric for comparing the performance of these 90CHAMBERS, UNGAR, AND LEEmark almost identical to our sumToTest benchmark, he reports an execution timeof 62ms, which we executed in 18ms on a machine 3 to 4 times faster than hismachine. This makes his systemÕs performance roughly comparable to oursystemÕs performance, even though his system relies on type declarations whileours does not. These results suggest that our compilation techniques do a good job cantly more powerful messagesplitting system. The initial message splitter described in this paper only splits amessage based on the type of the result of the previous message; the second-gener-ation message splitting system can use any type information constructed duringtype ßow analysis, especially the types of local slots. The message splitter mayelect to split messages even when the message is not immediately after a mergepoint, splitting all messages that intervene between the merge that lost the typeinformation and the message that needs the type information.Our goal for the combined type analyzer and extended message splitter is to Þrst authorÕs forth-coming dissertation.9ConclusionsMany researchers have attempted to boost the performance of dynamically-typedobject-oriented languages. The designers of Smalltalk-80 hard-wired the deÞni-tions of user-level arithmetic and control methods into the compiler, preventing theusers from changing or overriding them. Other researchers added type declarationsto Smalltalk, thereby hindering reuse and modiÞcation of code. We deviseddynamic customized compilation, static type prediction, type ßow analysis,message splitting, and message inlining to automatically extract and preserve statictype information. Our measurements suggest that our system runs just as fast asSmalltalk systems with type declarations and at least twice as fast as those withhard-wired methods. Researchers seeking to improve performance should improvetheir compilers instead of compromising their languages.SELFefÞciently as similar class-based systems; maps act as implementation-levelclasses and thus reclaim the efÞciency of classes for the implementation withoutinßicting class-based semantics on the SELF user. SELFÕs use of messages to accessvariables has absolutely no effect on the Þnal performance of SELF References1.Atkinson, R. G. Hurricane: An Optimizing Compiler for Smalltalk. In OOP-SLA Õ86 Conference Proceedings Pro-ceedings of the ACM SIGPLAN Õ90 Conference on Programming LanguageDesign and Implementation. Published as SIGPLAN Notices, 25, 6 (1990)150-162. Also to be published in Lisp and Symbolic Computation, Reclamation. In