c77843b7bfc1fec52d1763d51eb4d58f.ppt
- Количество слайдов: 104
IBM Research Applications of Type Constraints in Software Engineering Tools Frank Tip IBM T. J. Watson Research Center © 2004 IBM Corporation
IBM Research This Presentation is Based on Joint Work With § Ittai Balaban (New York University) § Dirk Bäumer (IBM Zurich Research Center) § Bjorn De Sutter (Ghent University) § Julian Dolby (IBM T. J. Watson Research Center) § Robert Fuhrer (IBM T. J. Watson Research Center) § Adam Kieżun (MIT) 2 © 2004 IBM Corporation
IBM Research § about 3000 people world-wide – 1600 at IBM T. J. Watson Research Center – other sites: Almaden, Austin, Zurich, Haifa, China, India § Software Technology Department – about 70 people, director Daniel Yellin – projects on: compiler optimization (Jikes. RVM), aspects, performance analysis, web services, refactoring, verification, XML, . . . – www. research. ibm. com/compsci/plansoft/index. html § ARTIST project (Advanced Refactoring Tools for Improving Software archi. Tecture) – Robert Fuhrer, Mandana Vaziri, Tim Klinger, Adam Kiezun (intern), Frank Tip (project leader) – collaboration with Eclipse JDT team at IBM Zurich – collaboration with IBM Rational – academic collaborations with Bjorn De Sutter (Ghent University), Ittai Balaban (NYU) 3 © 2004 IBM Corporation
IBM Research Other Research Activities § change impact analysis – given an old and a new version of a program, and a test that fails in the new version, find the subset of the source code changes responsible for the failure – with Barbara Ryder and Xiaoxia Ren (Rutgers) and Julian Dolby (IBM), Max Stoerzer (University of Passau) – papers: PASTE’ 01, OOPSLA’ 04 § Jax: an application extractor for Java – apply static analysis techniques to eliminate redundant functionality from Java applications, and apply size-reducing transformations – with Peter Sweeney, Chris Laffra, Aldo Eisma, David Streeter – transferred to IBM product (Web. Sphere Studio Device Developer) – papers: CACM’ 03, TOPLAS’ 02, OOPSLA’ 00, FSE’ 00, OOPSLA’ 99 4 © 2004 IBM Corporation
IBM Research Outline § background § type constraints for Java programs – notation and terminology – constraint generation rules § applications – generalization-related refactorings (OOPSLA’ 03) – customization of library classes (ECOOP’ 04) – refactorings for introducing generics (work in progress) § related work § conclusions and future work 5 © 2004 IBM Corporation
IBM Research Outline § background § type constraints for Java programs – notation and terminology – constraint generation rules § applications – generalization-related refactorings (OOPSLA’ 03) – customization of library classes (ECOOP’ 04) – refactorings for introducing generics (work in progress) § related work § conclusions and future work 6 © 2004 IBM Corporation
IBM Research Scope of our Research § start with a type-correct Java program P § for a given transformation that transforms P into P’ – we would like to check/guarantee that P’ is type-correct – we would like to check/guarantee that P’ has the same behavior as P – (in some cases) compute “maximal” P’ for which the above properties hold § we use type constraints to establish these properties – formalism for expressing relationships between program expressions that must hold in order for a program to be type-correct – traditionally used for type checking and type inference § transformations under consideration – refactorings: well-known maintenance operations, usually aimed at making code more flexible/general; proposed by the programmer – driven by static/dynamic analysis in link-time optimizer 7 © 2004 IBM Corporation
IBM Research Refactoring § refactoring: the application of behavior-preserving transformations to a program in order to improve a program’s design – eliminating undesirable program characteristics – e. g. , duplicated code, classes/methods that are too large, . . . – making existing classes/methods usable in new contexts – preparing for extensions – breaking up monolithic systems into components – introduction of design patterns § refactoring (noun): a specific program transformation. Usually identified by: – name (e. g. , “Extract Method”, “Pull Up Members”, . . . ) – preconditions – a specific set of transformations to be performed by a programmer or by an automated tool 8 © 2004 IBM Corporation
IBM Research Refactoring § pioneered by Griswold [1991], Opdyke [1992] & Johnson, leading to Smalltalk Refactoring Browser [Roberts 1992] § recently popularized by continuous-refinement methodologies such as “Extreme Programming” [Beck 2000] § catalogues of common refactorings: [Fowler 1999], [Kerievsky 2003] § Fowler describes refactorings as a series of steps to be performed by the programmer – manual refactoring is very error-prone – renewed interest in automated refactoring support in IDEs – refactoring support featured in Eclipse, IDEA, Omni. Core, . . . 9 Intelli. J © 2004 IBM Corporation
IBM Research Categories of Refactorings (see Fowler’s book) § making method calls simpler – Rename Method, Add/Remove Parameter, . . . § composing methods – Extract Method, Inline Local, . . . § moving features between objects – Move Method, Move Field, Extract Class, . . . § organizing data – Self-Encapsulate Field, Replace Data Value with Object, . . . § simplifying/eliminating conditionals – Replace Conditional with Polymorphism, . . . § dealing with generalization – Extract Interface, Pull Up Members, . . . 10 © 2004 IBM Corporation
IBM Research Eclipse (www. eclipse. org) § open-source (CPL) development environment – implemented in Java, XML – basis for commercial offerings by IBM (WSAD, WSDD) and others § plugin-architecture – plugins contribute views/perspectives – plugins provide extension points § state-of-the-art development environment for Java – quick-fixes, refactoring, type hierarchy view, call hierarchy, search facilities – support for other languages (C, Smalltalk, Aspect. J) § various IBM programs focused on Eclipse – Eclipse Innovation Grants for academics (2002, 2003) – Eclipse Technology Exchange meetings (ICSE, OOPSLA, ECOOP) § solid basis for research/education projects – Penumbra, Gild, Hipikat, ECESIS, . . . – Continuous Testing, Java Traits, Ownership Types, . . . 11 © 2004 IBM Corporation
IBM Research Demo: Eclipse Refactorings 12 © 2004 IBM Corporation
IBM Research Outline § background § type constraints for Java programs – notation and terminology – constraint generation rules § applications – generalization-related refactorings (OOPSLA’ 03) – customization of library classes (ECOOP’ 04) – refactorings for introducing generics (work in progress) § related work § conclusions and future work 13 © 2004 IBM Corporation
IBM Research Type Constraints § formalism developed in 1990 s – captures relationships between types of program constructs § original purpose: type checking/inference – prove that certain kinds of errors cannot occur at run-time – e. g. , no “message not understood” errors § we use a variation on the formalism from a book by Palsberg & Schwartzbach – adapted/extended to capture the semantics of Java 14 © 2004 IBM Corporation
IBM Research Type Constraints Notation [E] the type of expression E [M] the declared return type of method M [F] the declared type of field F Decl(M) the type that contains method M Param(M, i) the i-th parameter of method M , 15 subtype relation © 2004 IBM Corporation
IBM Research Syntax of Type Constraints [E] = [E’] the type of expression E must be the same as the type of expression E’ [E] [E’] the type of expression E is a proper subtype of the type of expression E’ [E] [E’] either [E] = [E’] or [E] [E’] [E] T the type of expression E is defined to be T [E] [E 1] or. . . or [E] [Ek] disjunction: at least one of subconstraints [E] [E 1], . . . , [E] [Ek] must hold 16 © 2004 IBM Corporation
IBM Research Generating Type Constraints declaration C v [v] C assignment E 1 = E 2 [E 2] [E 1] access E. f to field F [E. f] [F] [E] Decl(F) return E in method M [E] [M] method M in class C Decl(M) C this in method M direct call E. m(E 1, . . . , En) to method M [this] Decl(M) [E. m(E 1, . . . , En)] [M] [Ei] [Param(M, i)] [E] Decl(M) 17 © 2004 IBM Corporation
IBM Research Virtual Method Calls for a call E. m(E 1, . . . , En) to a virtual method M [E. m(E 1, . . . , En) ] [M] [Ei] [Param(M, i)] [E] Decl(M 1) or. . . or [E] Decl(Mk) where Root. Defs(M) = { M 1, . . . , Mk } Root. Defs(M) = { M’ | M overrides M’, and there exists no M’’ (M’’ M’) such that M’ overrides M’’ } 18 © 2004 IBM Corporation
IBM Research Constraints for Virtual Method Calls Dictionary put() Map put() public void foo(String s 1, String s 2) { Map Hashtable h = new Hashtable(); h. put(s 1, s 2); Hashtable put() } [h] Decl(Map. put(. . . )) or [h] Decl(Dictionary. put(. . . )) [h] Map Dictionary 19 © 2004 IBM Corporation
IBM Research Constraints for Overriding & Hiding if method M’ overrides method M, M’ M [Param(M’, i)] = [Param(M, i)] [M’] = [M] Decl(M’) < Decl(M) if field F’ hides field F Decl(F’) < Decl(F) 20 © 2004 IBM Corporation
IBM Research Casts for a cast (C)E [(C)E] C [E] [(C)E] or [(C)E] [E] if C is a class and [E] is a class § the latter constraint need not be generated if C or |E| is an interface § these constraints only capture the requirements for typecorrectness (not necessarily program behavior) § it is possible to avoid generating disjunctions by preserving the “directionality” of the cast 21 © 2004 IBM Corporation
IBM Research Outline § background § type constraints for Java programs – notation and terminology – constraint generation rules § applications – generalization-related refactorings (OOPSLA’ 03) – customization of library classes (ECOOP’ 04) – refactorings for introducing generics (work in progress) § related work § conclusions and future work 22 © 2004 IBM Corporation
IBM Research Refactoring for Generalization § several refactorings are concerned with generalization – moving methods/fields to superclasses and subclasses – splitting & merging of classes – manipulating the types of declarations § Chapter 11 of Fowler’s book mentions: – Extract Interface – Pull Up Member(s) – Push Down Member(s) – Extract Subclass – Generalize Type 23 © 2004 IBM Corporation
IBM Research Extract Interface – Recipe § select class C § select subset M of C’s methods § create interface I containing declarations of the methods in M § add inheritance “C implements I” § “Adjust client type declarations to use the interface” [Fowler, p. 342] 24 © 2004 IBM Corporation
IBM Research Extract Interface: An Example § List class with methods as follows: – add(Comparable) add an element – add. All(List) add contents of another List – iterator() iteration support – sort() sorts the list § List. Iterator class – implements java. util. Iterator; methods has. Next(), next() § Client class – create List; add some elements – add contents of another List; sort the List – print contents of the List § extract an interface Bag from List – declares add(Comparable), add. All(List), iterator() 25 © 2004 IBM Corporation
interface Bag { List/Bag Example (1) public Iterator iterator(); public List add(Comparable e); public List add. All(List v 0); } class List implements Bag { int size = 0; Comparable[] elems = new Comparable[10]; public Iterator iterator(){ return new List. Iterator(this); } public List add(Comparable e) { if (this. size + 1 == this. elems. length) { Comparable[] new. Elems = new Comparable[2 * this. size]; System. arraycopy(this. elems, 0, new. Elems, 0, this. size); this. elems = new. Elems; } this. elems[this. size++] = e; return this; } public List add. All(List v 1) { java. util. Iterator i = v 1. iterator(); for (; i. has. Next(); this. add((Comparable)i. next())); return this; } public void sort() { /* insertion sort */ } } 26
List/Bag Example (2) class List. Iterator implements java. util. Iterator { private int count = 0; private List v 2; List. Iterator(List v 3){ v 2 = v 3; } List public boolean has. Next(){ return this. count < this. v 2. size; } public Object next(){ return this. v 2. elems[this. count++]; } } public class Client { public static void main(String[] args) { List v 4 = create. List(); populate(v 4); update(v 4); sort. List(v 4); print(v 4); } static List create. List(){ return new List(); } static void populate(List v 5){ v 5. add("foo"). add("bar"); } static void update(List v 6) { List v 7 = new List(). add("zap"). add("baz"); v 6. add. All(v 7); } static void sort. List(List v 8){ v 8. sort(); } List static void print(List v 9) { for (Iterator iter = v 9. iterator(); iter. has. Next(); ) System. out. println("Object: " + iter. next()); } 27 }
IBM Research Problem Statement § identify all declarations that can be updated to make use of the newly extracted interface § want to be able to reason about: – correctness of the solution – maximality of the solution 28 © 2004 IBM Corporation
IBM Research Using Type Constraints § declared types of variables, fields, parameters constrained by: – field access, method calls – assignments, parameter-passing § several other invariants must be maintained to preserve typecorrectness & program behavior § Observation: all these constraints can be stated succinctly and uniformly using type constraints 29 © 2004 IBM Corporation
IBM Research List. add(), Bag. add() [Bag. add()] = [List. add()] List. add. All(), Bag. add. All() [v 0] = [v 1] [Bag. add. All()] = [List. add. All()] List. iterator() List [v 3] List. add() List [List. add()] List. add. All() [v 1] Bag, List [List. add. All()] List. Iterator. iterator() [v 3] [v 2] List. Iterator. has. Next() [v 2] List. Iterator. next() [v 2] List Client. main() [Client. create. List()] [v 4], [v 4] [v 5], [v 4] [v 6], [v 4] [l 8], [v 4] [l 9] Client. create. List() List [Client. create. List()] Client. populate() [v 5] Bag, [List. add()] Bag Client. update() [List. add()] [v 7], [List. add()] Bag, [v 6] Bag, [v 7] [v 1] Client. sort. List() [v 8] List Client. print() [v 9] Bag 30 © 2004 IBM Corporation
IBM Research Observation § the constraints for the original program contain all the information we need § some declarations cannot be updated List [v 3] [v 2] List [v 4] [v 8] List § other variables are less constrained [v 1] Bag 31 © 2004 IBM Corporation
IBM Research Algorithm for Determining “Updatable” Declarations § iterative algorithm for determining non-updatable declarations – first determine declarations that cannot be updated because of member access (e. g. , [v 2] List, [v 8] List) – if x is non-updatable, and there is a type constraint [y] [x], [y] = [x], or [y] < [x] then y is non-updatable § iterate until fixed-point is reached 32 © 2004 IBM Corporation
IBM Research Non-Updatable Declarations for the Example Program { v 2, v 3, v 4, v 8, Client. create. List() } (consistent with earlier result) 33 © 2004 IBM Corporation
IBM Research Justification (Details in Paper) § type-correctness – updating the “updatable” declaration elements results in a program that satisfies all type constraints § preservation of behavior – argument based on the fact that method dispatch, cast/instanceof behavior do not depend on declared types § maximality – updating any non-updatable declarations will result in the violation of type constraints 34 © 2004 IBM Corporation
IBM Research Another Refactoring: Pull Up Members class A {. . . } ? [this] Decl(B. foo()) B [B. foo()] B [this] [B. foo()] class B extends A { public B foo(){ return this; } } 35 © 2004 IBM Corporation
IBM Research Pull Up Members (2) class A { public B foo(){ return this; } } class B extends A {. . . } [this] Decl(A. foo()) A [A. foo()] B [this] ≤ [A. foo()] 36 © 2004 IBM Corporation
IBM Research Other Refactorings § Generalize Type – update the type of a declaration E – use type constraints to determine allowable supertypes/subtypes – may enable Pull Up Members in certain cases § Extract Subclass – splitting of a class – can be treated similarly as Extract Interface § Push Down Members – the “inverse” of Pull Up Members – similar issues 37 © 2004 IBM Corporation
IBM Research Perspective § infer from original program a system of ordering constraints between types of declaration elements – original program is just one possible solution § Extract Interface – declarations: variables – locations of members: constants § Pull Up Members – declarations: constants – locations of members: variables § Generalize Type – selected declaration: variable – all other declarations & locations of members: constants 38 © 2004 IBM Corporation
IBM Research Demo: Extract Interface & Generalize Type 39 © 2004 IBM Corporation
IBM Research Outline § background § type constraints for Java programs – notation and terminology – constraint generation rules § applications – generalization-related refactorings (OOPSLA’ 03) – customization of library classes (ECOOP’ 04) – refactorings for introducing generics (work in progress) § related work § conclusions and future work 40 © 2004 IBM Corporation
IBM Research Class Libraries § class libraries improve programmer productivity – programmers don’t have to waste time developing & debugging standard infrastructure § but. . . class libraries are often implemented with some typical/ average usage pattern in mind § for example: container class implementations assume that: – elements are accessed often & frequently – a large number of elements is stored Þ performance loss if the actual usage of a library class differs from this typical usage pattern Þ “My. Hash. Table”, “Smart. Hashtable”, . . . in various benchmarks 41 © 2004 IBM Corporation
IBM Research Our Approach § derive custom versions from library classes § rewrite application to use these custom versions § ship custom library classes with application § technical foundations: – use type constraints to determine where custom classes can be used – use profile information to determine where introducing custom classes is profitable – use static analysis and profile information to decide how to customize 42 © 2004 IBM Corporation
IBM Research Example Program class Example { void foo(Map m){ foo(M m){ H r 1 = new H(); Hashtable r 1 = new Hashtable(); JTree tree = new JTree(r 1); H r 2 = new H(); Hashtable r 2 = new Hashtable(); H r 3 = new H(); Hashtable r 3 = new Hashtable(); r 2. put(“FOO”, “BAR”); bar(r 3); r 2 = r 3; r 2. put. All(m); bar(“HELLO”); } void bar(Object o){ bar(O o){ H r 4 = (H) o; Hashtable r 4 = (Hashtable) o; if (r 4. contains(“FOO”)) {…} } } 43 Object O O String S Dictionary S D D M Map M Hashtable H H © 2004 IBM Corporation
IBM Research How to customize? class Example { void foo(M m){ H r 1 = new H(); JTree tree = new JTree(r 1); H r 2 = new H()H 1(); H r 3 = new H()H 2(); H(); r 2. put(“FOO”, “BAR”); bar(r 3); r 2 = r 3; r 2. put. All(m); bar(“HELLO”); } void bar(O o){ H r 4 = (H) o; if (r 4. contains(“FOO”)) {…} } } 44 O S D M H H 1 H 2 © 2004 IBM Corporation
IBM Research O How to customize? class Example { void foo(M m){ H r 1 = new H(); JTree tree = new JTree(r 1); H H 1 = newnew H()H 1(); r 2 = H()H 1(); H r 3 = newnew H()H 2(); H 2 r 3 = H()H 2(); r 2. put(“FOO”, “BAR”); bar(r 3); r 2 = r 3; r 2. put. All(m); bar(“HELLO”); } void bar(O o){ H r 4 = (H) o; if (r 4. contains(“FOO”)) {…} } } 45 S H 1 D H 2 M H H 1 H 2 © 2004 IBM Corporation
IBM Research O How to customize? class Example { void foo(M m){ H r 1 = new H(); JTree tree = new JTree(r 1); H H 1 r 2 = new H()H 1(); H H 1 r 3 = new H()H 1(); r 2. put(“FOO”, “BAR”); bar(r 3); r 2 = r 3; r 2. put. All(m); bar(“HELLO”); } void bar(O o){ H r 4 = (H) o; if (r 4. contains(“FOO”)) {…} } } 46 S H 1 D H 2 M H © 2004 IBM Corporation
IBM Research O How to customize? class Example { void foo(M m){ H r 1 = new H(); JTree tree = new JTree(r 1); H 1 H AH r 2 = new H()H 1(); H 1 H()H 1(); H AH r 3 = new H()H 2(); r 2. put(“FOO”, “BAR”); bar(r 3); r 2 = r 3; r 2. put. All(m); bar(“HELLO”); } void bar(O o){ H r 4 = (H) o; if (r 4. contains(“FOO”)) {…} } } 47 S H 1 D AH H 2 H 1 M H H 2 • update allocations of library types • update declarations © 2004 IBM Corporation
IBM Research O Restrictions? S call to: javax. swing. JTree(Hashtable) class Example { void foo(M m){ H r 1 = new H(); JTree tree = new JTree(r 1); H r 2 = new H(); H r 3 = new H(); r 2. put(“FOO”, “BAR”); bar(r 3); r 2 = r 3; r 2. put. All(m); bar(“HELLO”); } void bar(O o){ H r 4 = (H) o; if (r 4. contains(“FOO”)) {…} } } 48 H 1 D AH M H H 2 • type correctness • interface compatibility • preserve behavior of cast and instanceof operations © 2004 IBM Corporation
IBM Research Outline of Approach § generate type constraints for program – additional constraints generated to ensure that behavior of cast/instanceof operations is preserved § constraint simplification – rewrite/replace all constraints to use “≤” only § solve the resulting constraint system § rewrite the program’s declarations and allocation sites to use the inferred types 49 © 2004 IBM Corporation
IBM Research Preserving the Behavior of Cast & instanceof § we want to change declarations and allocation sites – need to ensure that cast/instanceof operations succeed and fail in exactly the same cases as before – use points-to analysis to approximate the set of objects to which the cast/instanceof is applied – easily expressed using constraint (to be replaced with a ≤ constraint) public class Example { void zip(){ zap(new Hashtable()); // A 1 zap(new String()); // A 2 } void zap(Object o){ Hashtable h = (Hashtable)o; // C } } 50 A 1 ≤ C A 2 C © 2004 IBM Corporation
IBM Research O Type constraints class Example { void foo(M m){ d 1 r 1 H r 1 ==new H(); new a 1(); JTree tree = new JTree(r 1); d 2 r 2 H r 2 ==new H(); new a 2(); d 3 r 3 H r 3 ==new H(); new a 3(); r 2. put(“FOO”, “BAR”); bar(r 3); r 2 = r 3; r 2. put. All(m); bar(“HELLO”); } void bar(d 4 o){ bar(O o){ d 5 r 4 H r 4 ==(H) o; o; (c 1) if (r 4. contains(“FOO”)) {…} } } 51 S § § § § a 1 ≤ d 1 ≤ H a 2 ≤ d 2 a 3 ≤ d 3 d 2 ≤ D v d 2 ≤ M D AH H 1 M H H H 2 d 3 ≤ d 4 d 3 ≤ d 2 ≤ M S ≤ d 4 c 1 ≤ d 4 v d 4 ≤ c 1 ≤ d 5 ≤ H v d 5 ≤ AH a 3 ≤ c 1 S c 1 ≤ H d 5 ≤ H © 2004 IBM Corporation
IBM Research O Type constraints M H d 5 d 4 c 1 S a 3 52 S d 2 H d 1 d 3 a 2 a 1 § § § § a 1 ≤ d 1 ≤ H a 2 ≤ d 2 a 3 ≤ d 3 d 2 ≤ D v d 2 ≤ M D AH H 1 M H H H 2 d 3 ≤ d 4 d 3 ≤ d 2 ≤ M S ≤ d 4 c 1 ≤ d 4 v d 4 ≤ c 1 ≤ d 5 ≤ H v d 5 ≤ AH d 5 ≤ H a 3 ≤ c 1 S c 1 ≤ H © 2004 IBM Corporation
IBM Research O Constraint Solving S d 5 ≤ HT AH M H {O, S, H, d 4 H 1, H 2, D, M, AH} {O, S, H, d 5 H 1, H 2, D, M, AH} {O, S, H, S c 1 H 1, H 2, D, M, AH} a 3 {O, S, H, H 1, H 2} 53 D d 1 ≤ H {O, S, H, d 2 H 1, H 2, D, M, AH} H {O, S, H, H 1, H 2} H H H 2 {O, S, H, d 1 H 1, H 2, D, M, AH} {O, S, H, d 3 H 1, H 2, D, M, AH} a 2 H 1 M a 1 ≤ d 1 a 1 {O, S, H, H 1, H 2} © 2004 IBM Corporation
IBM Research Rewriting the Example Program M H {AH} d 5 {O} d 4 c 1 S {AH} d 2 d 3 {AH} {H 2} a 3 {H 2} 54 a 2 {H 1} class Example { void foo(M m){ H r 1 ==new H(); H r 1 d 1 r 1 = new H(); new a 1(); H JTree tree = new JTree(r 1); AH r 2 = new a 2(); d 2 r 2 = new H 1(); AH d 2 H 1(); AH r 3 = new a 3(); d 3 r 3 = new H 2(); AH d 3 H 2(); r 2. put(“FOO”, “BAR”); {H} bar(r 3); d 1 bar(r 3); r 2 = r 3; r 2. put. All(m); bar(“HELLO”); } } void bar(d 4 o){ bar(O o){ d 5 r 4 = (c 1) o; AH d 5 r 4 = (H 2) o; (H 2) (c 1) if (r 4. contains(“FOO”)) {…} } } a 1 } } {H} © 2004 IBM Corporation
IBM Research Creating Custom Classes O S 1. create custom “profiling” Hashtable – number of succeeding/failing get/put operations M H simulate caching schemes – AH determine how often allocation sites are executed – D H 1 H 2 2. static analysis (using “gnosis” framework developed at IBM) – construct call graph (0 -CFA, distinct allocation sites for classes of interest) – compute type estimates – escape analysis 3. generate custom implementations: H 1, H 2, … – generated from template (using C preprocessor) 4. rewrite bytecode for the program 55 © 2004 IBM Corporation
IBM Research Generating Custom Classes O S 1. lazy vs. eager allocation 2. synchronized vs. unsynchronized 3. optimizing edge cases D AH H 1 M H H 2 4. caching of frequently accessed objects 5. removal of unused fail-safe iteration code 6. … 56 © 2004 IBM Corporation
IBM Research § _202_jess Applied Customizations – specialization of Hashtable keys (String/Integer) – synchronization removal on frequently used Vectors _209_db – use caching to optimize consecutive Vector-retrievals – synchronization removal on frequently used Vectors _218_jack – 99% of all search operations are on empty Hashtables – lazy allocation, removal of bookkeeping for fail-safe iterators – synchronization removal on Hashtables Jax – most containers remain small, decrease initial container size Hyper. J – optimization of empty Hashtables, removal of bookkeeping for fail-safe iterators – synchronization removal Chess* – frequent iteration over Hashtables of fixed, small size – use smaller initial size Pmd * – the vast majority of a huge number of allocated Hash. Sets remains empty – lazy allocation, removal of bookkeeping for fail-safe iterators § § § 57 *no synchronization removal because of GUI-related © 2004 IBM Corporation multi-threading in these benchmarks
IBM Research Speedups § § 58 customization of: – java. util. * containers – String. Buffers (desynchronization only) measurements taken on Hyper. Threaded Pentium 4 @ 2. 8 Ghz running Linux 2. 4. 21 © 2004 IBM Corporation
IBM Research Heap Consumption § 59 significant reduction in heap consumption on _218_jack because of lazy allocation of many Hashtable-objects that remain empty © 2004 IBM Corporation
IBM Research Impact on Application Size § § 60 note: original size of _209_db is only 6 KB. – 15 KB of custom container classes are added on large benchmarks (>100 Kb), the size increase is <= 12% © 2004 IBM Corporation
IBM Research Outline § background § type constraints for Java programs – notation and terminology – constraint generation rules § applications – generalization-related refactorings (OOPSLA’ 03) – customization of library classes (ECOOP’ 04) – refactorings for introducing generics (work in progress) § related work § conclusions and future work 61 © 2004 IBM Corporation
IBM Research Java Generics § generics (parametric polymorphism) to be introduced in Java 1. 5 – classes can have type parameters that have optional bounds – reduces need for downcasts class Hashtable<Key, Value> {. . . } class Tree<Elem extends Comparable<Elem>> {. . . } Hashtable<Integer, String> table = new Hashtable<Integer, String>(); . . . String s = table. get(some. Integer); 62 © 2004 IBM Corporation
IBM Research Generic Collections § in most Java applications, the use of Collection classes is the main source of down-casts § the standard libraries for Java 1. 5 contain generic versions of existing Collection classes – Vector<T> instead of Vector – Hash. Map<K, V> instead of Hash. Map § goal: refactor applications that use non-generic collections – make them use generic collections instead – use type inference to infer element types – remove downcasts 63 © 2004 IBM Corporation
IBM Research class A { Example 1 public void foo(){ Vector v 1 = new Vector(); String s 1= "aaa"; this. insert(v 1, s 1); String s 2= (String)v 1. get(0); } public void insert(List v 2, Object o){ v 2. add(o); } } 64 © 2004 IBM Corporation
IBM Research Example 1 (refactored) class A { public void foo(){ Vector<String> v 1 = new Vector<String>(); String s 1= "aaa"; this. insert(v 1, s 1); String s 2= (String)v 1. get(0); } public void insert(List<String> v 2, String o){ v 2. add(o); } } § update “collection” declarations § remove casts § note update of declaration of o 65 © 2004 IBM Corporation
IBM Research public void bar(){ List v 1= new Vector(); v 1. add(new Float(3. 4)); this. reverse(v 1); Float f 1 = (Float) v 1. iterator(). next(); } public void baz(){ List v 2 = new Vector(); v 2. add(new Integer(17)); this. reverse(v 2); Integer i 1 = (Integer) v 2. iterator(). next(); } public void reverse(List v 3){ for (int t=0; t < v 3. size()/2; t++){ Object temp = v 3. get(v 3. size()-1); v 3. add(v 3. size()-1, v 3. get(t)); v 3. add(t, temp); } } 66 Example 2 © 2004 IBM Corporation
IBM Research public void bar(){ List<Number> v 1= new Vector<Number>(); v 1. add(new Float(3. 4)); this. reverse(v 1); Float f 1 = (Float) v 1. iterator(). next(); Example 2 (version 1) } public void baz(){ List<Number> v 2 = new Vector<Number>(); v 2. add(new Integer(17)); this. reverse(v 2); Integer i 1 = (Integer) v 2. iterator(). next(); } public void reverse(List<Number> v 3){ for (int t=0; t < v 3. size()/2; t++){ Number temp = v 3. get(v 3. size()-1); v 3. add(v 3. size()-1, § element types v 3. get(t)); v 3. add(t, temp); } } 67 “merged” in reverse() § cannot remove casts in callers © 2004 IBM Corporation
public void bar(){ List<Float> v 1= new Vector<Float>(); v 1. add(new Float(3. 4)); this. reverse(v 1); Float f 1 = (Float) v 1. iterator(). next(); Example 2 (version 2) } public void baz(){ List<Integer> v 2 = new Vector<Integer>(); v 2. add(new Integer(17)); this. reverse(v 2); Integer i 1 = (Integer) v 2. iterator(). next(); } public <T> void reverse(List<T> v 3){ for (int t=0; t < v 3. size()/2; t++){ § obs: no flow of values between different invocations of reverse() T temp = v 3. get(v 3. size()-1); v 3. add(v 3. size()-1, v 3. get(t)); § need for context-sensitive v 3. add(t, temp); } 68 } analysis § introduction of type parameters
IBM Research Outline of Approach § context inference – use low-cost variation on Agesen’s Cartesian Product Algorithm (CPA) [Agesen: 95] for inferring relevant contexts – simultaneously computes points-to information for expressions and a set of contexts for each method § type inference – generate type constraints for the program that explicitly encode context information – solving the type constraints produces element types for declarations and allocations of container class types § source rewriting – analyze (element) types inferred for different contexts, introduce type parameter if necessary 69 © 2004 IBM Corporation
IBM Research public void bar(){ Context Inference [●] List v 1= new Vector(); // L 1 v 1. add(new Float(3. 4)); this. reverse(v 1); [●] Float f 1 = (Float) v 1. iterator(). next(); } [●] public void baz(){ List v 2 = new Vector(); // L 2 v 2. add(new Integer(17)); this. reverse(v 2); [●] Integer i 1 = (Integer) v 2. iterator(). next(); } [●, L 1] [●, L 2] [●, Lext] [●, L 1] [●, L 2] public void reverse(List v 3){ for (int t=0; t < v 3. size()/2; t++){ Object temp = v 3. get(v 3. size()-1); v 3. add(v 3. size()-1, v 3. get(t)); v 3. add(t, temp); } } 70 © 2004 IBM Corporation
IBM Research public void bar(){ [●] |new Vector()|[●] Vector<X 1> List v 1= new Vector(); // |new Vector()|[●] ≤ |v 1|[●] L 1 Example Constraints v 1. add(new Float(3. 4)); |new Float(3. 4)|[●] Float this. reverse(v 1); |new Float(3. 4)|[●] Types[●](v 1) Float f 1 = (Float) v 1. iterator(). next(); |v 1|[●] ≤ |v 3|[●, L 1] } public void baz(){ [●] |new Vector()|[●] Vector<X 2> List v 2 = new Vector(); // L 2 |new Vector()|[●] ≤ |v 2|[●] v 2. add(new Integer(17)); |new Integer(17)|[●] Integer this. reverse(v 2); |new Integer(17)|[●] Types[●](v 2) Integer i 1 = (Integer) v 2. iterator(). next(); |v 2|[●] ≤ |v 3|[●, L 2] } public void reverse(List v 3){ [●, L 1], [●, L 2], [●, Lext] for (int t=0; t < |v 3. get( )|[●, L 1] Elem[●, L 1](v 3) v 3. size()/2; t++){ |v 3. get( )|[●, L 2] Elem[●, L 2](v 3) Object temp = v 3. get(v 3. size()-1); ] Elem[●, L ](v 3) |v 3. get( )|[●, L |temp| |v 3. get( )|[●, L 1] ≤ Ext [●, L 1] Ext |v 3. get( )|[●, L 2] ≤ |temp|[●, L 2] v 3. add(v 3. size()-1, |v 3. get( )| v 3. get(t)); [●, L Elem |temp|[●, L |v 3. get( )|[●, L 1] ≤ Ext] ≤ [●, L 1](v 3) Ext] v 3. add(t, temp); |v 3. get( )|[●, L 2] ≤ Elem[●, L 2](v 3) |v 3. get( )|[●, LExt] ≤ Elem |temp|[●, L 1] ≤ Elem[●, L 1](v 3) [●, LExt](v 3) } |temp|[●, L 2] ≤ Elem[●, L 2](v 3) |temp|[●, LExt] ≤ Elem[●, LExt](v 3) } 71 © 2004 IBM Corporation
IBM Research Constraint Solving § standard propagation-based solver – computes a type for each constraint variable |E| – in cases where multiple types can be chosen for an expression E, a heuristics-based choice is made (a least specific type for containerrelated expressions, a most specific type for other expressions) – different types may be computed for the same expression in different contexts (e. g. , |E| 1 and |E| 2) § element types are unified across ≤ constraints § processing type variables – – 72 a type variable is bound by matching it with a concrete set of types matching two type variables results in their unification type variables may be left unbound (e. g. , in incomplete programs) use approximate solution (e. g. , element type Object) when processing programs with code like v. add(v) © 2004 IBM Corporation
IBM Research public void bar(){ [●] List v 1= new Vector(); // L 1 Constraint Solving v 1. add(new Float(3. 4)); Elem[●](v 1) = Float this. reverse(v 1); Float f 1 = (Float) v 1. iterator(). next(); } public void baz(){ [●] List v 2 = new Vector(); // L 2 Elem[●](v 2) = Integer v 2. add(new Integer(17)); this. reverse(v 2); Integer i 1 = (Integer) v 2. iterator(). next(); } public void reverse(List v 3){ [●, L 1], [●, L 2], [●, Lext] for (int t=0; t < v 3. size()/2; t++){ Object temp = v 3. get(v 3. size()-1); Elem[●, L 1](v 3) = Float v 3. add(v 3. size()-1, v 3. get(t)); v 3. add(t, temp); Elem[●, L 2](v 3) = Integer } Elem[●, Lext(v 3) = Object } 73 © 2004 IBM Corporation
IBM Research public void bar(){ List<Float> v 1= new Vector<Float>(); Code v 1. add(new Float(3. 4)); this. reverse(v 1); Float f 1 = (Float) v 1. iterator(). next(); } public void baz(){ List<Integer> v 2 = new Vector<Integer>(); v 2. add(new Integer(17)); this. reverse(v 2); Integer i 1 = (Integer) v 2. iterator(). next(); } public <T> void reverse(List<T> v 3){ for (int t=0; t < v 3. size()/2; t++){ T temp = v 3. get(v 3. size()-1); v 3. add(v 3. size()-1, v 3. get(t)); v 3. add(t, temp); } } 74 Generation © 2004 IBM Corporation
IBM Research Results benchmark #container allocations #container declarations #casts removed %casts removed Hanoi 4028 3 6 20 14 70 JUnit 5317 24 63 54 21 39 JLex 7841 17 45 71 53 75 Java. Cup 10598 19 78 502 373 74 Mango 1 2808 2 9 2 2 100 Mango 2 2808 3 13 4 2 50 Mango 3 75 LOC 2808 1 17 10 0 0 © 2004 IBM Corporation
IBM Research Demo: Prototype “Genericize” Refactoring 76 © 2004 IBM Corporation
IBM Research Outline § background § type constraints for Java programs – notation and terminology – constraint generation rules § applications – generalization-related refactorings (OOPSLA’ 03) – customization of library classes (ECOOP’ 04) – refactorings for introducing generics (work in progress) § related work § conclusions and future work 77 © 2004 IBM Corporation
IBM Research Related Work on Customization § automatic data structure selection for SETL – see [Schonberg et al. ’ 81] § automatic component selection – see, e. g. , [Hogstedt et al. ’ 01, Yellin ’ 03] – purely profile-based, no static analysis – all possible component implementations supplied up-front § automatic optimization of data structures in specific domains – e. g. , data structure selection for sparse matrix problems § optimizations applied to specific container classes – see, e. g. , [Beckmann & Wang, Friedman et al. ’ 01] – e. g. , prefetching, incrementalizing rehash operations § much related work on partial evaluation and program specialization – see e. g. , [Schultz, Lawall, Consel ’ 03] 78 © 2004 IBM Corporation
IBM Research Other Related Work § type inference and type-directed transformation have been used in the translation of large COBOL programs for Y 2 K compliance [Eidorff et al. 99, Ramalingam et al. 99] § informal characterization of type constraints [Opdyke’ 92, Seguin’ 00, Tokuda & Batory’ 01] § detecting overspecific variables [Halloran & Scherlis’ 02] § generating proposals for refactoring class hierarchies using concept analysis [Snelting & Tip’ 00] § inferring generic types in Java programs [Duggan’ 99, Donovan et al. ’ 04, Von Dincklage & Diwan’ 04] 79 © 2004 IBM Corporation
IBM Research Future Work § in progress: support for migration between functionally equivalent classes – e. g. , from Vector to Array. List, Hashtable to Hash. Map – limitations on migration due to interaction with external code – application: upgrading of “legacy” applications § variation on Java in which programmers only refer to interface types such as Set, Map, List instead of concrete types such as Hash. Set, Tree. Map, Array. List – use customization techniques to select implementation – similar in spirit to the SETL work at NYU by Paige, Schonberg, et al. in the 1970 s and 1980 s § other generics-related refactorings – select a declaration & change its type into a type parameter 80 © 2004 IBM Corporation
IBM Research Conclusions § type constraints are a useful tool for supporting refactorings and related program transformations – checking of preconditions – determining allowable source-code modifications – enables reasoning about program behavior § applications – refactorings related to generalization – customization of library classes – refactorings for introducing generics – more refactorings in the works § implemented in Eclipse – Extract Interface, Generalize Type available now – generics refactorings planned for Eclipse 3. 1 – freely available from www. eclipse. org 81 © 2004 IBM Corporation
EXTRA SLIDES 82
IBM Research Typical Refactoring Scenario § user proposes a transformation by interacting with GUI/Wizards in IDE § system checks if preconditions are met § system determines necessary/allowable source code updates § systems shows before/after “diff” view § user confirms § program works as before 83 © 2004 IBM Corporation
IBM Research Solving the Constraints § naive approach – explicitly enumerate all values; each expression type in { C, I } – for each solution, determine if constraints are satisfied § cost: O(2 n), where n is the number of declarations of type C 84 © 2004 IBM Corporation
IBM Research Object-Oriented Type Systems “A type system is a tractable syntactic method for proving the absence of certain program behaviors by classifying phrases according to the kinds of values they compute” [Benjamin C. Pierce, 2002] Traditional applications of type systems: – enhance readability/understandability – prove/guarantee that certain kinds of run-time errors will not occur during program execution (e. g. , “message not understood”) – foundation for abstractions & language features (e. g. , module systems) – enable optimizations (e. g. , replace dynamic dispatch with direct call) 85 © 2004 IBM Corporation
IBM Research Some Terminology § type: set of objects that share properties (e. g. , supported operations) – in Java, there is a direct correspondence between types and classes and interfaces in the inheritance hierarchy § static typing: type information is explicit in the source code – consistency checks can be performed by a compiler (type checking) – Note: some run-time checking may still be needed § type checking: checking certain consistency properties of programs that contain explicit type declarations – to guarantee the absence of run-time errors – a program that type-checks is (statically) type-correct § type inference – in dynamically typed languages, types of expressions are inferred from their usage – also used in statically typed languages for optimization (e. g. , certain run-time checks may be proven obsolete through analysis) § type constraints – formalism for expressing relationships between program expressions that must hold in order for a program to be type-correct – used for type checking as well as for type inference 86 © 2004 IBM Corporation
IBM Research Observations § cannot update variable e 1 because method get. Name() is called on e 1, which is not declared in Billable § cannot update variable e 2 because method get. Address() is called on e 2, which is not declared in Billable § updating the return type of find. Employee() produces type mismatch in assignment to e 2 § updating the cast produces type mismatch in assignment to e 1 87 © 2004 IBM Corporation
IBM Research Observations § Observations: – – type of v 2 must be List, because of field access v 2. size type of v 3 must be List, because of assignment v 2 = v 3 type of v 8 must be List, because of call v 8. sort() type of v 4 must be List because it is passed as an argument to Client. sort. List(), implying an assignment v 8 = v 4 – return type of Client. create. List() must be List because of assignment v 4 = Client. create. List() § Conclusion: – v 0, v 1, v 5, v 6, v 7, v 9, and the return types of List. add(), List. add. All(), Bag. add. All() can be given type Bag 88 © 2004 IBM Corporation
IBM Research Conclusions & Future Work § customization: a technique for library-level optimizations – – – use type constraints to determine where applicable use profile information to determine where useful use static analysis and profile information to select optimizations § strong results – speedups up to 76. 7% (18. 8 -24. 1% on average) – heap consumption reduced by up to 45. 9% (11. 9% on average) – modest increase in app. size (<12% on large applications) § future work: – – 89 apply additional optimizations apply to additional library classes self-customizing classes incorporate into whole-program optimizers • e. g. , Jax [Tip et al. 02], IBM WSDD Smart. Linker © 2004 IBM Corporation
IBM Research Detailed Speedup Results 90 © 2004 IBM Corporation
IBM Research Detailed Heap/Size Results 91 © 2004 IBM Corporation
IBM Research Implementation § implemented in Eclipse using existing refactoring framework [Baeumer et al. 01] – Extract Interface – Generalize Type – Pull Up Members – Push Down Members § determining type constraints nontrivial for several language features – arrays – member types (inner classes) – exceptions – overloading 92 © 2004 IBM Corporation
IBM Research Demonstration of Eclipse Refactoring Support § § Rename Class – remove ugly prefix: JX_RTA -> RTA § Extract Method – method RTA. process() too long – extract process. Current. Call. Sites. Wrt. Processed. Classes() – est. Iterations() – undo – est. Iterations() with next line --- two return values – convert local to field – est. Iterations with next line OK now § Inline Method – RTA. move. New. To. Current. Classes() § Inline Local Variable – inline “call. Site” in process. Current. Call. Sites. Wrt. Processed. Classes() § 93 Basic Stuff: – texthovers: Java. Doc – ctrl-hover: Code + Hyper. Link – Ctrl-T: hierarchy – code completion Extract Constant – DONE_ESTIMATE at end of RTA. process() § Pull Up Members © 2004 IBM Corporation
Example public class Employee { public String get. Name(){ return _name; } public String get. Address(){ return _address; } public int get. Rate(){ return _rate; } public boolean has. Special. Skill(){ return _has. Special. Skill; } private int _rate; private boolean _has. Special. Skill; private String _name; private String _address; } public class Time. Sheet { public double charge(Employee emp, int days){ int base = emp. get. Rate() * days; if (emp. has. Special. Skill()) return base * 1. 05; else return base; } } Example taken from Fowler’s “Refactoring”, p. 342 © 2004 IBM Corporation 94 IBM Research
IBM Research Example public interface Billable { int get. Rate(); boolean has. Special. Skill(); } public class Employee implements Billable { // contents of this class same as before } public class Time. Sheet { public double charge(Billable emp, int days){ int base = emp. get. Rate() * days; if (emp. has. Special. Skill()) return base * 1. 05; else return base; } } 95 Example taken from Fowler’s “Refactoring”, p. 342 © 2004 IBM Corporation
IBM Research But updating any of these references to Employee leads to compilation errors. . . public class Personnel { public static Employee find. Employee(String name) throws Not. Found. Exception { for (int t=0; t < employees. size(); t++){ Employee e 1 = (Employee)employees. element. At(t); if (e 1. get. Name(). equals(name)) return e 1; } throw new Not. Found. Exception(); } public static String find. Address(String name) throws Not. Found. Exception { Employee e 2 = find. Employee(name); return e 2. get. Address(); } private static Vector employees; } © 2004 IBM Corporation 96
IBM Research Context Inference § assume that allocation sites in a program are labeled – distinct labels L 1, . . . , Lk for container-related allocation sites – a single “blob” label ● used for all other allocation sites – distinct label Lext represents collections created outside the application § for each method m, infer a set of contexts Contexts(m) – each context represents a set of callers of a method – identified by a list of labels, one for each parameter; e. g. , [L 1, L 2, ●, ●] § for each expression E that occurs in the body of method m for which Contexts(m), infer a points-to set Objects (E) – set of labels; e. g. , PT(E) = {L 1, L 2, L 9, ●} § compute context-sensitive call graph – compute for each pair <call-site, context>, a set of <method, context> pairs – make conservative assumptions about entry point methods 97 © 2004 IBM Corporation
IBM Research Context Inference § we assume a given set of entry points – e. g. , all public methods – to be specified by the user of the refactoring tool § conservative assumptions about objects bound to parameters of entry point methods – depends on declared type of the parameter § conservative assumptions about calls to external methods for which source code is unavailable § use Class Hierarchy Analysis (CHA) [Grove et al. 95] to approximate behavior of dynamic dispatch § null constants, literals, primitive values modeled as objects 98 © 2004 IBM Corporation
IBM Research Auxiliary Definitions for Context Inference Rules § set of objects assumed to be bound to parameters of entry-point methods { Lext } if T ≤ Collection External. Objects(T) = { ● } if T Collection {Lext, ● } otherwise § construct contexts for call sites that occur in method m for which Contexts(m) Select. Contexts( , E 0, . . . , Ek) = { [p 0, . . . , pk] | pi Objects (Ei), 0 ≤ i ≤ k } 99 © 2004 IBM Corporation
IBM Research Some of the Context Inference Rules T 0. m(T 1, . . . , Tn) is an entry point, pi External. Objects(Ti), = [p 0, . . . , pn], 1 ≤ i ≤ n Contexts(T 0. m(T 1, . . . , Tn)) pi Objects (Param(T 0. m(T 1, . . . , Tn) )) (C 1) (C 2) m contains assignment E 1=E 2, Contexts(m) Objects (E 2) Objects (E 1) (C 3) m contains call E 0 new TL(E 1, . . . , En) to constructor m’, T ≤ Collection, Contexts(m) L Objects (E 0) (C 4) m contains call E 0 new TL(E 1, . . . , En) to constructor m’, T Collection, Contexts(m) ’ Select. Contexts( , E 0, . . . , En), 0 ≤ i ≤ n ’ Contexts(m’) ● Objects (E 0) Objects (Ei) Objects ’(Param(m’, i)) 100 (C 5) (C 6) (C 7) © 2004 IBM Corporation
IBM Research Constraint Generation § constraint generation rules similar to those used for generalization-related refactorings – constraint variables annotated with subscript that identifies their “containing” context – additional rules that model the behavior of operations on collections § constraint variable Elem (E) represents the element type of container objects in Objects (E) – similar: Key (E), Value (E) type for Map-style collections § notation: New. Type(T) denotes a parameterized version of type T with a fresh type variable 101 © 2004 IBM Corporation
IBM Research Some of the Constraint Generation Rules m contains assignment E 1=E 2, Contexts(m) |E 2| ≤ |E 1| (B 1) m contains direct call E T. n(E 1, . . . , Ek) to method m’, T Collection Contexts(m), ’ Select. Contexts( , E 1, . . . , Ek), E’i = Param(m’, i), 1 ≤ i ≤ k |E| |m’| ’ (B 4) |Ei| ≤ |E’i| ’ (B 5) m contains call E 0. add(E 1) to method m’, Contexts(m), Decl(m’) ≤ Collection |E 1| Types (E 0) T Types (E) T ≤ Elem (E) 102 (B 16) |E 1| ≤ |E 2| ’ (B 24) Elem (E 1) = Elem ’(E 2) (B 27) © 2004 IBM Corporation
IBM Research Constraint Generation for new Expressions m contains expression E 0 new T(E 1, . . . , Ek) to constructor m’, T Collection, Contexts(m), ’ = Select. Contexts( , E 0 , . . . , Ek), E’i = Param(m’, i), 0 ≤ i ≤ k |E 0| T (B 2) |Ei| ≤ |E’i| ’ (B 3) m contains expression E 0 new T(E 1, . . . , Ek), T ≤ Collection, Contexts(m), T’ = New. Type(T) |E 0| T’ 103 (B 14) © 2004 IBM Corporation
IBM Research Code Generation § source code updating for a method m is trivial if there is one context for m, or if the types inferred for the expressions in m are the same in all contexts § if for a given expression E in method m, different types are computed in different contexts for m we attempt to introduce a type parameter for E – need to determine which (if any) other expressions must have the same type as E – a bound on a type parameter T of method m is needed if expressions of type T are constrained to be of a type X more specific than Object in some context of m • use a common upper bound of all such types X § in programs with failing casts, the type constraint system may not have a solution in a given context – approach: merge all contexts for methods with failing casts, and continue solving (context-insensitive solution) § a down-cast (T)E is redundant if the inferred type for E is a subtype of T – in all contexts for E 104 © 2004 IBM Corporation
c77843b7bfc1fec52d1763d51eb4d58f.ppt