A program storage device, readably by a machine, tangibly embodying instructions to perform method steps for constructing a call graph whereby for each method m, a set of types Sm of objects that may occur in method m is determined for each field f, a set of types Sf of objects is determined that may be stored in field f, the method comprising: determining the allocation sites inside the body of method m; determining the set of directly called methods M′ inside the body of method m; and determining the set of virtually called methods M″ inside the body of method m.

Patent
   7003507
Priority
Sep 18 2000
Filed
Mar 30 2001
Issued
Feb 21 2006
Expiry
Apr 15 2023
Extension
746 days
Assg.orig
Entity
Large
14
12
EXPIRED
11. A method for constructing a set of types occurring within a method, the method comprising:
selecting a program p for constructing a call graph representation thereof;
wherein the program p contains zero or more fields ff and at least two methods mm;
wherein each method m1 in mm has a single body b;
constructing for each method m in mm, a set of types Sm of objects which occur therein;
constructing for each field f in ff, a set of types Sf of objects stored therein;
identifying one or more allocation sites inside the body b of each of method m;
determining a set of methods M′ that are directly called within the body b of each method m and propagating types from a set of types SM′ to the set of types Sm and from of the set of types Sm to the set of types SM′;
determining a set of methods M″ that are virtually called within the body b of each method m and propagating types from a set of types SM″ to the set of types Sm and from of the set of types Sm to the set of types SM″;
determining a set of fields f that are
read in the body b of each method m, and propagating types from the set of types Sf to the set of types Sm; and
written in the body b of each method m, and propagating types from the set of types Sm to the set of types Sf.
1. A program storage device, readable by a machine, tangibly embodying programming instructions to perform method steps for constructing a set of types occurring within a method, the programming instructions comprising:
selecting a program p for constructing a call graph representation thereof;
wherein the program p contains zero or more fields ff and at least two methods mm;
wherein each method m1 in mm has a single body b;
constructing for each method m in mm, a set of types Sm of objects which occur therein;
constructing for each field f in ff, a set of types Sf of objects stored therein;
identifying one or more allocation sites inside the body b of each of method m;
determining a set of methods M′ that are directly called within the body b of each method m and propagating types from the set of types SM′ to the set of types Sm and from of the set of types Sm to the set of types SM′;
determining a set of methods M″ that are virtually called within the body b of each method m and propagating types from the set of types SM″ to the set of types Sm and from the set of types Sm to the set of types SM″;
determining a set of fields f that are
read in the body b of each method m, and propagating types from the set of types Sf to the set of types Sm; and
written in the body b of each method m, and propagating types from the set of types Sm to the set of types Sf.
9. A computer program product for constructing a set of types occurring within a method, the computer program product comprising:
a storage medium readable by a processing circuit and storing instructions for execution by the processing circuit for performing a method comprising:
selecting a program p for constructing a call graph representation thereof;
wherein the program p contains zero or more fields ff and at least two methods mm;
wherein each method m1 in mm has a single body b;
wherein for each method m2 in mm, the call graph representation includes a corresponding node;
wherein the call graph representation includes zero or more edges corresponding to connections between two or more of nodes;
constructing for each method m in mm, a set of types Sm of objects which occur therein;
constructing for each field f in ff, a set of types Sf of objects stored therein;
identifying one or more allocation sites inside the body b of each of method m;
determining a set of methods M′ that are directly called within the body b of each method m and propagating types from the set of types SM′ to the set of types Sm and from of the set of types Sm to the set of types SM′;
determining a set of methods M″ that are virtually called within the body b of each method m and propagating types from the set of types SM″ to the set of types Sm and from of the set of types Sm to the set of types SM″;
determining a set of fields f that are
read in the body b of each method m, and propagating types from the set of types Sf to the set of types Sm; and
written in the body b of each method m, and propagating types from the set of types Sm to the set of types Sf.
2. The program storage device according to claim 1, further comprising the programming instructions of:
determining the set of all types T that are allocated in the body of method m, and adding each element of the set of all types T to the set of types Sm.
3. The program storage device according to claim 2, further comprising the programming instructions of:
for each direct call to a methods M′ in the body b of the method m performing the steps of:
adding any type that occurs in the set of types Sm and that is a subtype of the type of a parameter of the methods M′ to the set of types SM′; and
adding any type that occurs in the set of types SM′ and that is a subtype of a return type of the methods M′ to the set of types Sm.
4. The program storage device according to claim 3, further comprising the programming instructions of:
for each virtual call to the methods M′ in the body b of the method m:
using the set of types Sm, determine each of the methods M″ that may be reached by a dynamic dispatch;
adding any type that occurs in the set of types Sm and that is a subtype of the type of a parameter of the methods M″ to athe set of types SM″,
adding any type that occurs in the set of types SM″ and that is a subtype of the return type of the methods M″ to the set of types Sm.
5. The program storage device according to claim 4, further the programming instructions of:
for each field f read by the method m, adding any type that occurs in the set of types Sf to the set of types Sm; and
for each field f with the set of all types T written by the method m, adding any type that occurs in the set of types Sm and that is a subtype of the set of all types T to the set of types Sf.
6. The program storage device according to claim 1, further comprising:
constructing a call graph representation;
wherein for each method m2 in mm, the call graph representation includes a corresponding node; and
wherein the call graph representation includes zero or more edges corresponding to connections between two or more of nodes.
7. The program storage device according to claim 6, further comprising the programming instructions of:
using the call graph, as previously constructed, in a reporting tool to report call graph information to a user.
8. The program storage device according to claim 6, further comprising the programming instructions of:
using the call graph, as previously constructed, in a compiler as a basis for performing optimizations such as inlining.
10. The computer program product according to claim 9, further comprising:
determining the set of all types T that are allocated in the body of method m, and adding each element of the set of all types T to the set of types Sm.
12. The method according to claim 11, further comprising:
determining the set of all types T that are allocated in the body of method m, and adding each element of the set of all types T to the set of types Sm.
13. The method according to claim 12, further comprising:
for each direct call to a method M′ in the body b of the method m performing the steps of:
adding any type that occurs in the set of types Sm and that is a subtype of a type of a parameter of the method M′ to the set of types SM′; and
adding any type that occurs in the set of types SM′ and that is a subtype of a return type of the method M′ to the set of types Sm.
14. The method according to claim 13, further comprising:
for each virtual call to the method M′ in the body b of the method m:
using the set of types Sm, determine each of the methods M″ that may be reached by a dynamic dispatch:
adding any type that occurs in the set of types Sm and that is a subtype of a type of a parameter of the method M″ to the set of types SM″;
adding any type that occurs in the set of types SM″ and that is a subtype of the return type of the method M″ to the set of types Sm.
15. The method according to claim 14, further comprising:
for each field f read by the method m, add any type that occurs in the set of types Sf to the set of types Sm; and
for each field f with the set of all types T written by the method m, add any type that occurs in the set of types Sm and that is a subtype of the with set of all types T to the set of types Sf.
16. The method according to claim 11, further comprising the step of:
using the call graph, as previously constructed, in a compiler as a basis for performing optimizations such as inlining.
17. The method according to claim 11, further comprising:
constructing a call graph representation;
wherein for each method m2 in mm, the call graph representation includes a corresponding node; and
wherein the call graph representation includes zero or more edges corresponding to connections between two or more of nodes.
18. The method according to claim 17, further comprising the step of:
using the call graph, as previously constructed, in a reporting tool to report call graph information to a user.

This is non-provisional patent application is based on the provisional patent application Ser. No. 60/233,591 to Frank Tip et al, for “Scalable Propagation-Based Call Graph Construction Algorithms” filed Sep. 18, 2000, which is commonly assigned herewith to International Business Machines Corporation, and is hereby incorporated herein in its entirety by reference.

All of the material in this patent application is subject to copyright protection under the copyright laws of the United States and of other countries. As of the first effective filing date of the present application, this material is protected as unpublished material. However, permission to copy this material is hereby granted to the extent that the copyright owner has no objection to the facsimile reproduction by anyone of the patent documentation or patent disclosure, as it appears in the United States Patent and Trademark Office patent file or records, but otherwise reserves all copyright rights whatsoever.

1. Field of the Invention

This invention generally relates to the field of object-oriented programming, specifically to the analysis and optimization of object-oriented programs, and in particular to the field call graph construction algorithms such as RTA (Rapid Type Analysis).

2. Description of the Related Art

A key task that is required by most approaches to whole-program optimization is the construction of a call graph approximation. Through use of a call graph, methods can be removed that are not reachable from the main method, dynamically dispatched method calls can be replaced with direct method calls, methods calls can be inlined when there is a unique target, and more sophisticated optimizations can be performed such as interprocedural constant propagation, object inlining, and transformations of the class hierarchy. In the context of object-oriented languages with dynamic dispatch, the crucial step in constructing a call graph is to compute a conservative approximation of the set of methods that can be invoked by a given virtual (i.e., dynamically dispatched) method call.

Call-graph construction algorithms have been studied intensively in the 1990s. While their original formulations use a variety of formalisms, most of them can be recast as set-based analyses. The common idea is to abstract an object into the name of its class, and to abstract a set of objects into the set of their classes. For any given call site e.m( ), the goal is then to compute a set of class names Se that approximates the run-time values of the receiver expression e. Once the sets Se are determined for all expressions e, the class hierarchy can be examined to identify the methods that can be invoked.

Most call graph construction algorithms differ primarily in the number of sets that are used to approximate run-time values of expressions. Examples:

NUMBER OF SETS USED TO
APPROXIMATE RUN-TIME
VALUES OF EXPRESSIONS ALGORITHM NAME
No Sets Class Hierarchy Analysis (CHA)9,10
One set for the whole program Rapid Type Analysis (RTA)5,6
One set per expression O-CFA (Control-Flow Analysis)17,33
Several sets per expression k-CFA, k > 017,33

Intuitively, algorithms that use more sets compute more precise call graphs, but need more time and space to do the construction. In practice, the scalability of the algorithms at either end of the spectrum is fairly clear. The CHA and RTA algorithms at the low end of the range scale well and are widely used. The k-CFA algorithms (for k>0) at the high end seem not to scale well at all.17 The scalability of 0-CFA remains doubtful, mostly due to the large amounts of space required to represent the many different sets that arise. Recent work by Fähndrich et al. give grounds for optimism, although their recent results are obtained on a machine with 2,048 Megabytes of memory.37 In the case of Java, another complicating factor for 0-CFA is that sets of class names need to be computed for locations on the run-time stack. Those locations are unnamed, and to facilitate 0-CFA, it seems necessary to first do a program transformation that names all the locations in some fashion, as done in various recent work.21, 38, 41 Such transformations introduce both time and space overhead. With the investigation of the scalability of 0-CFA still pending, there is a need in the prior art to address the following:

The following prior art algorithms progressively take more information into account when resolving virtual method calls.

1. Name-Based Resolution (RA)

Reachability Analysis (RA) is a simple algorithm for constructing call graphs that only takes into account the name of a method. (A slightly more advanced version of this algorithm relies on the equality of method signatures instead of method names. Variations of RA have been presented in many places and used in the context of tree-shakers for Lisp. 16, 34

RA can be defined in terms of a set variable R (for “reachable methods”) that ranges over sets of methods, and the following constraints, derived from the program text:

Intuitively, the first constraint reads “the main method is reachable,” and the second constraint reads “if a method is reachable, and a virtual method call e.m( . . . ) occurs in its body, then every method with name m is also reachable.” It is straightforward to show that there is a least set R that satisfies the constraints, and a solution procedure that computes that set. The reason for computing the least R that satisfies the constraints is that this maximizes the complement of R, i.e., the set of unreachable methods that can be removed safely.

Class Hierarchy Analysis (CHA)

The constraint system for RA can be extended to also take class hierarchy information into account. The result is known as class hierarchy analysis (CHA).9,10 The following notation StaticType(e) is used to denote the static type of the expression e, SubTypes(t) to denote the set of declared subtypes of type t, and the notation StaticLookup(C, m) to denote the definition (if any) of a method with name m that one finds when starting a static method lookup in the class C. Like RA, CHA uses just one set variable R ranging over sets of methods. The constraints:

Intuitively, the second constraint reads: “if a method is reachable, and a virtual method call e.m( . . . ) occurs in the body of that method, then every method with name m that is inherited by a subtype of the static type of e is also reachable.”

Type Analysis (RTA)

CHA can be further extended to take class-instantiation information into account. The result is known as rapid type analysis (RTA).5, 6 RTA uses both a set variable R ranging over sets of methods, and a set variable S which ranges over sets of class names. The variable S approximates the set of classes for which objects are created during a run of the program. The constraints:

Intuitively, the second constraint refines the corresponding constraint of CHA by insisting that C{grave over ( )}S, and that the third constraint reads: “S contains the classes that are instantiated in a reachable method.”

RTA is easy to implement, scales well, and has been shown to compute call graphs that are significantly more precise than those computed by CHA.6 There are several whole-program analysis systems that rely on RTA to compute call graphs (e.g., the JAX application extractor40). In the Section entitled “Results”, RTA is used as the baseline against which the new call graph construction methods and process technique is compared, according to the present invention.

Related Work

Propagation-Based Algorithms

The idea of doing a propagation-based program analysis with one set variable for each expression is well known. This so-called monovariant style of analysis can be done in O(n3) time where n is the number of expressions. When the goal is to construct a call graph approximation in object-oriented or functional languages, then that style of analysis is known as 0-CFA, and when the goal is to do points-to analysis for C programs, then that style of analysis is often referred to as “Andersen's analysis”.3, 31 0-CFA has been implemented for a variety of languages, including dynamically-typed object-oriented languages, functional languages, and statically-typed object-oriented languages, including Java.1,3,11,19,21,28,29,31,33,38 The experience has been that the effectiveness of the approaches is language-dependent, and perhaps even programming-style dependent.

The idea of polyvariance is to associate more than one set variable with each expression, and thereby obtain better precision for each call site. Polyvariant analysis was pioneered by Sharir and Pnueli, and Jones and Muchnick.25, 32 In the 1990s the study of polyvariant analysis has been intensive. Well known are the k-CFA algorithms of Shivers, the poly-k-CFA of Jagannathan and Weeks, and the Cartesian product algorithm of Agesen.1, 2, 24, 33 A particularly simple polyvariant analysis was presented by Schmidt.30 Frameworks for defining polyvariant analyses have been presented by Stefanescu and Zhou, Jagannathan and Weeks, and Nielson and Nielson.23,26,36 Successful applications of polyvariant analysis include the optimizing compiler of Chambers et al, and of Hendren et al, and the partial evaluator of Consel.,8,12,17 The inventors are not aware if these polyvariant approaches have been tried on programs of 100,000+ lines of code.

Algorithms not Based on Propagation

Calder and Grunwald investigated a particularly simple approach to inlining based on the unique name measure, that is, inlining in cases where there statically is a unique target for a given call site.7, 20, 35

A variation of 0-CFA is the unification-based approach, also known as the equality-base approach. This approach was pioneered by Steensgaard in the context of paints-to analysis for C.20, 35 A comparison of Andersen's analysis and Steensgaard's analysis has been presented by Shapiro and Horwitz.31 The unification-based approach is cheaper and less precise than the 0-CFA-style approach.

A broader comparison was given by Foster, Fähndrich, and Aiken; they compared both polymorphic versus monomorphic and equality-based versus inclusion-based points-to analysis.15 Their main conclusion is that the monomorphic inclusion-based algorithm is a good choice because 1) it usually beats the polymorphic equality-based algorithm, 2) it is not much worse than the polymorphic inclusion-based algorithm, and 3) it is simple to implement because it avoids the complications of polymorphism.

An experimental comparison of RTA and a unification-based approach to call graph construction was carried out by DeFouw, Grove, and Chambers.11 Their paper presents a family of algorithms that blend propagation and unification, thereby in effect dynamically determining which set variables to unify based on how propagation proceeds. Members of the family include RTA, 0-CFA, and a number of algorithms with cost and precision in between. These above algorithms although useful do not use static criteria to decide which set variables are to be merged and do not avoid analysis of the run-time stack.

Ashley also presented an algorithm that blends unification and propagation, in the setting of Scheme.4

Accordingly, there is a need in the prior art to overcome the above problems of (i) analysis of the stack; (ii) high computational overhead; and (iii) high complexity to implement, and to provide, a new process or method, computer readable medium and system to overcome the above problems.

Briefly, according to the present invention, disclosed is a method and system for A program storage device, readably by a machine, tangibly embodying instructions to perform method steps for constructing a call graph whereby for each method M, a set of types SM of objects that may occur in method M is determined for each field F, a set of types SF of objects is determined that may be stored in field F, the method comprising: determining the allocation sites inside the body of method M; determining the set of directly called methods M′ inside the body of method M; and determining the set of virtually called methods M″ inside the body of method M.

Implemented are several novel algorithms in the context of JAX, an application extractor for Java, and shown that they all scale to a 325,000-line program. One property of the present process technique is that it does not require simulation of the run-time stack, which makes them easy to implement and which helps efficiency. The present process technique associate a single distinct set with each class, method, and/or field (but not each expression) in an application. Surprisingly, for detecting unreachable methods, the inexpensive RTA does almost as well as the seemingly more powerful algorithms. However, if the number of edges in the call graph, or number of call sites with a single target is of issue, one of the techniques present in this invention obtains the current beast tradeoff between speed and precision.

In summary, the results for the most precise of the new process techniques look as follows:

The algorithms do not require exorbitant amounts of space. All the measurements for the present invention were performed on a IBM ThinkPad 600E PC with 288 MB memory. None of the present benchmarks required more than 200 MB of heap space.

The subject matter which is regarded as the invention is particularly pointed out and distinctly claimed in the claims at the conclusion of the specification. The foregoing and other objects, features, and advantages of the invention will be apparent from the following detailed description taken in conjunction with the accompanying drawings.

FIG. 1 is a schematic overview of the algorithms and their relationship to each other showing the cost and accuracy, according to the present invention.

FIG. 2 is a table that lists the benchmark applications that were used to evaluate the algorithm and present technique, and provides a number of relevant statistics, according to the present invention.

FIG. 3 is a table that shows, for each of the algorithms and techniques in the present invention implemented, the total number of types (instantiated classes), the average number of types available in each method body, and the latter as a percentage of the former, according to the present invention.

FIG. 4 is a table for each of the benchmarks, the number of methods in the call graphs computed by RTA, MTA, FTA, and XTA, according to the present invention.

FIG. 5 is a table illustrating the shows the results of the call graph edges according to the present invention.

FIG. 6 shows a table that classifies the virtual call sites in each of he benchmark applications as “unreached”′ (i.e., occurring in an unreached method), “monomorphic” (i.e., having a single target), or “polymorphic” (i.e., having multiple targets), according to the present invention.

FIG. 7 is a table which shows a detailed comparison of the call graphs constructed by RTA and MTA/FTA/XTA, for each of the benchmarks, according to the present invention.

FIG. 8 illustrates a table of the running time for the RTA, MTA, FTA, and XTA algorithms on each of the benchmarks (Measurements taken on an IBM ThinkPad 600E PC with a 300 Mhz processor and 288 MB of main memory, according to the present invention.

FIG. 9 is a high-level block diagram of the procedures used in the Pseudo-code, according to the present invention.

It is important to note, that these embodiments are only examples of the many advantageous uses of the innovative teachings herein. In general, statements made in the specification of the present application do not necessarily limit any of the various claimed inventions. Moreover, some statements may apply to some inventive features but not to others. In general, unless otherwise indicated, singular elements may be in the plural and visa versa with no loss of generality.

Overview

The patent is divided into the following areas. New Algorithms, Implementation Issues, Results, Related Work, Future Work, Pseudo Code for New XTA Algorithm, Hardware and Software Implementation Issues.

A set-based framework is used to present both some existing and some new algorithms. This enables easy comparison and help put the present invention in context. FIG. 1 shows the relationships between four new algorithms CTA, MTA, FTA, and XTA, and four well-known previous algorithms: RA (Reachability Analysis), CHA (Class Hierarchy Analysis), RTA (Rapid Type Analysis), and 0-CFA. The ordering from left to right corresponds to increased accuracy and increased cost. The increased cost stems from increased amounts of information used in resolving virtual method calls. The algorithms to the left of the new algorithms have been shown to scale well, whereas the scalability of 0-CFA remains doubtful. In Section entitled “Results” the scalability of the new algorithms is demonstrated.

New Algorithms

The new algorithms and new process techniques use multiple set variables that range over sets of classes. These set variables are associated with program entities such as classes, methods, and fields. Giving each program entity a more precise “local” view of the types of objects available then call sites are resolved more accurately.

Separate Set for Methods and Fields (XTA)

The first algorithm, which is called XTA, uses a distinct set variable SM for each method M, and a distinct set variable Sx for each field x. This analysis is called XTA. The following notation ParamTypes(M) is used for the set of static types of the arguments of the method M (excluding method M's this pointer), and the notation ReturnType(M) for the static return type of M. The function SubTypes ( ) is extended to work on a set of types:

SubTypes(Y)=4 SubTypes(y)

The following constraints define XTA:

The second constraint refines the corresponding constraint of RTA by: (i) insisting that objects of the target class C are available in the local set SM associated with M; (ii) adding two inclusions that capture a flow of data from M to M′, and from M′ back to M, and (iii) stating that an object of type C (the “this” pointer) is available in M′. The third constraint refines the corresponding constraint of RTA by adding the class name C to just the set variable for the method M. The fourth constraint reflects a data flow from a field to a method body, and the fifth constraint reflects a data flow from a method body to a field, taking hierarchy information and creation point information into account.

Algorithms in the Space Between RTA and XTA

There is a spectrum of analyses between RTA and XTA. The following are exemplary embodiments:

The following is a summary of the algorithms and present techniques tested. For a given program, define:

C: the number of classes in the program.

M: the number of methods in the program.

F: the number of fields in the program.

In the following table, the first column gives the number of set variables used to approximate run-time values of expressions.

NUMBER OF SETS ALGORITHM
0 CHA
1 RTA
custom character CTA
custom character + custom character MTA
custom character + custom character FTA
custom character + custom character XTA

All of the algorithms and present techniques and also 0-CFA can be executed in O(n2×custom character) time, where n is the number of set variables.28 0-CFA can be viewed as an extension of XTA in the following way. Rather than using just one set variable for each method, 0-CFA uses one set variable for each argument and each expression that evaluates to an object, including references to objects on the run-time stack. The main problem for 0-CFA is that stack locations are unnamed in the Java virtual machine, so it seems necessary to first do a program transformation that names all the locations in some fashion, as done in various recent work.21, 38, 41

The lattice that was shown previously in FIG. 1 illustrates the relationships between the algorithms in terms of cost and accuracy. In the Section entitled “Related Work” discussed further are how these algorithms compare to other algorithms.

Implementation Issues

The previously described algorithms and present techniques in the Section entitled “Algorithms” have been implemented in the context of JAX, an application extractor for Java. Jikes Bytecode Toolkit (JikesBT) is a publically available class library from IBM for manipulating Java class files. See online URL (www.alphaworks.ibm.com/tech/jikesbt). JikesBT is used for reading in the Java class files that constitute an application, and for creating an internal representation of the classes in which the string-based references of the class file format are represented by pointer references. JAX uses RTA for constructing call graphs, and the present algorithms reuse several important data structures that were previously designed for RTA. Only about 4000 lines of new code is needed to implement the algorithms and present techniques described above.

The implementation performs the XTA algorithm in an iterative, propagation-based style. Three work-lists are associated with each program component (i.e., method or field) that keep track of “processed” types that have been propagated onwards from the component to other components, “current” types that will be propagated onwards in the current iteration, and “new” types that are propagated to the component in the current iteration and that will be propagated onwards in the next iteration.

The FTA and MTA algorithms are implemented by using a shared set for all the methods and fields in a class, respectively. Note that in the case of MTA (FTA) propagations between different methods (fields) in the same class are not needed. However, once a type is propagated to a method (field) in class C, the other methods (fields) in C still have to be revisited because onward propagations from those methods (fields) may have to take place.

A combination of array-based and hash-based data structures are used that allow efficient membership-test operations, element addition, and iteration through all elements. It is important to make al of these operations very efficient. Since the propagation of elements is filtered by types of method parameters, method return types, and types of fields, it is very important to efficiently implement subtype-tests. The approach relies on associating two integers with each class, corresponding to a pre-order and a post-order traversal of the class hierarchy. Using this numbering scheme, the existence of a subclass-relationship between two classes can be determined in unit time by comparing the associated numbers.

Applying the algorithms to realistic Java applications forced us to address several pragmatic issues:

The above technique in certain cases is unnecessarily conservative, because objects passed to a library method do not always pollute the global set SE. Based on these observations, the implementation in one embodiment of the present invention incorporates two refinements to the above scheme:

For a range of benchmarks, five characteristics of the results of MTA, FTA, and XTA, with the results of RTA as a baseline are measured:

Of particular interest is the classification of call sites into monomorphic and polymorphic ones, and a detailed study is provided of how algorithms in the present invention improves on RTA. While the number of reachable methods decreases little, significant reductions have been found in the number of edges in the constructed call graphs for several of the benchmarks. More importantly, found is a significant increase in the number of monomorphic call sites when moving from RTA to, especially, XTA.

Benchmark Characteristics

FIG. 2 is a table 200 that lists the benchmark applications that were used to evaluate the algorithm and present technique, and provides a number of relevant statistics for each of them. These benchmarks cover a wide spectrum of programming styles and are publically available (except for it Mockingbird and Reservation System).

Hanoi is an interactive applet version of the well-known “Towers of Hanoi” problem, and is shipped with JAX. ICE Browser (See online URL www.icesoft.no) is a simple internet browser. Mockingbird (mBird) is a proprietary IBM tool for multi-language interoperability. It relies on, but uses only limited parts of, several large class libraries (including Swing, now part of JDK 1.2, and IBM's XML parser). Cinderella (See online URL www.cinderella.de) is an interactive geometry tool used for education and self-study in schools and universities. CindyApplet is an applet that allows users to interactively solve geometry exercises that were created with Cinderella. It is contained in the same class file archive as Cinderella. Lotus eSuite Sheet and Lotus eSuite Chart are interactive spreadsheet and charting applets, which are examples shipped with Lotus eSuite productivity suite (DevPack 1.5 version). (See online URL www.esuite.lotus.com). JavaFig (version 1.43 (22.02.99)) (See online URL tech-www.informatik.uni-hamburg.de/applets/javafig is a Java version of the xfig drawing program.) BLOAT (See online URL www.cs.purdue.edu/homes/hosking/pjama.html) is a byte-code optimizer developed at Purdue University. Version 6.3 of JAX itself was used as a benchmark. javac (See www.specbench.org) is the SPEC JVM 98 version Sun's javac compiler. The largest benchmark, Reservation System, which is an interactive front-end for an airline, hotel, and car rental reservation system developed by an IBM customer, and consists of approximately 325,000 lines of Java source code.

The table 200 in FIG. 2. illustrates the number of classes, methods, and fields for each of the benchmarks. The table 200 also shows the number of reference-typed fields in the application (i.e., fields whose type is a reference to a class), which is indicated between brackets in the “fields” column. The system in the present invention creates one set for each reference-typed field that is accessed from a reached method. Hence, this number is a bound on the number of field-sets that are created. Table 200 also shows the number of virtual call sites in each benchmark. For reasons described below, virtual calls to methods outside the application are excluded from this statistic.

Set Sizes

Statistics such as the number of reached methods and the percentage of uniquely resolved method calls are the measures by which call graph construction algorithms are traditionally compared. Since such measures all depend on the number of types available in a method, it is interesting to examine the average set of types available in each method as a more “absolute”′ measure. FIG. 3 is a Table 300 that shows, for each of the algorithms implemented, the total number of types (instantiated classes), the average number of types available in each method body, and the latter as a percentage of the former. In the case of RTA, which uses only one set, the average number of types per method is the same as the total number of types.

Table 300 illustrates several interesting things:

While these reductions in average set size are substantial, it seems that there is still room for improvement. Computed on average, for Reservation System, about 200 types are available in each method when XTA is used. This number seems high, considering that the average size of a method is in the order of 15–20 lines of source code.

Reached Methods

FIG. 4 illustrates a table 400 shows, for each of the benchmarks, the number of methods in the call graphs computed by RTA, MTA, FTA, and XTA. Also shown are the percentage reductions of MTA, FTA, and XTA relative to RTA.

These statistics do not include abstract methods, which do not have a body, do not call other methods, and which cannot be the target of a dynamic dispatch. The rationale for excluding abstract methods has to do with the following observation: In cases where a virtual method m is called, but where m cannot be the target of a dynamic dispatch, it is possible to remove the m's body and make m into an abstract method without affecting program behavior (in fact, this is one of the optimizations performed by JAX). Therefore, counting abstract methods as first-class citizens makes it impossible to distinguish between call graphs that contain the same set of method headers, but different sets of method implementations. One could of course provide detailed statistics that include the number of non-abstract methods as well as the number of non-abstract methods, but this additional detail is not very worthwhile.

In summary:

The next measure examined is the number of edges in the computed call graphs. In determining this number, each direct call site (i.e., a call that does not involve a dynamic dispatch) is counted as one, and each virtual call site as the number of “target” methods that may be invoked by a dynamic dispatch from that site. Multiple calls to the same method m within a method body are counted separately (although analyses in the present invention treats each of these calls similarly).

Since it is not known whether or not classes outside the application have been instantiated, it is not possible to accurately determine the number of targets of calls to virtual methods outside the application. Therefore, in performing these measurements, any calls to methods outside the application are ignored.

FIG. 5 is a table 500 which shows the results. It is clear that several of the new algorithms do eliminate substantially more edges than RTA does. The results can be summarized as follows:

One of the goals in the optimization of object-oriented programs is to find “monomorphic” virtual call sites from which only a single method can be invoked. Such call sites can be transformed into direct calls, and subsequently inlined and optimized further.

FIG. 6 shows a table 600 that classifies the virtual call sites in each of he benchmark applications as “unreached” (i.e., occurring in an unreached method), “monomorphic” (i.e., having a single target), or “polymorphic” (i.e., having multiple targets). Calls to methods outside the application are ignored again, since it cannot accurately be determine the number of targets in such cases. Using table 600, the following conclusions have been reached:

In summary, RTA does a very good job in classifying virtual call sites as monomorphic. For the benchmarks examined in this patent, only 7.8% of all virtual call sites are classified as polymorphic (on average), which leaves little room for improvement. XTA classifies an average of 7.0% of all virtual call sites as polymorphic.

Detailed Comparison

FIG. 7 is a table 700, which shows a detailed comparison of the call graphs constructed by RTA and MTA/FTA/XTA, for each of the benchmarks. Each call site in the RTA call graph is classified as one of the following:

To determine how much more accurate the MTA/FTA/XTA algorithms are when compared to RTA in relative terms, the following is observed:

Hence, what remains are the poly-to-mono and the poly-to-poly categories. The ratio between these categories reflects the relative improvement of MTA/FTA/XTA over RTA.

As an example, consider Reservation System, the largest benchmark. This application contains a total of 23,640 virtual call sites. If (i) all call sites are subtracted that are determined to be monomorphic by RTA, and (ii) all call sites are substracted that are determined to be unreachable by XTA, the result is 2,824 call sites that are determined to be polymorphic by RTA. XTA determines that 569 of these call sites are, in fact, monomorphic. Hence, XTA is capable of devirtualizing 569/2,824=20.1% of the call sites deemed polymorphic by RTA. Applying this line of reasoning to table 700, results in:

FIG. 8 illustrates a table 800 of the running time for the RTA, MTA, FTA, and XTA algorithms on each of the benchmarks (Measurements taken on an IBM ThinkPad 600E PC with a 300 Mhz processor and 288 MB of main memory. The Sun JDK 1.1.8 VM is used with the just-in-time compiler developed at the IBM Tokyo Research Laboratory.22 None of the benchmarks required more than 200 MB of heap space.) In summary, the XTA algorithm is up to 8.3 times slower than RTA. The correlation between the slowdown factor and program size appears to be weak: XTA is only 5.0 times slower than RTA on Reservation System. The present invention should scale well and have no problems with million-line programs.

Surprisingly, the MTA and FTA algorithms were in several instances somewhat slower than XTA. To date the source of these slowdowns has not been determined. A possible explanation is that the increased number of types available in a method results in additional work in resolving the call sites within that method. However, it seems unlikely that this would negate all the benefits from a decreased number of propagations between sets. An efficient implementation of MTA/FTA (e.g., using techniques by Fähndrich et al is expected to be significantly more efficient than XTA.13

Assessment

The experiments have demonstrated that it is feasible to construct propagation-based call graph construction algorithms that use more than a single set of objects to approximate the run-time values of expressions. Regarding the precision of these algorithms, the following is observed:

In light of the improved results of XTA over FTA in some cases, the XTA algorithm is the best choice. If heap space is at a premium, FTA offers reduced space consumption in exchange for a slight loss of precision. MTA seems a poor choice since it computes call graphs that have roughly the same precision as those computed by RTA, but it is more complex to implement. Although no data for CTA is presented herein, CTA is less accurate than MTA, and the same arguments can be made to argue why it is not a very good choice.

Additional Considerations

A comparison of the algorithms and present techniques, 0-CFA, and the settings of Sundaresan et al. or Ishizaki et al. seems to require a framework in which a program transformation names all stack locations. 21, 38 This would be a significant extension to the framework of the present invention so it may be easier to do a comparison in the settings of Sundaresan and Isizaki.21, 38 Questions that could be addressed by such a comparison include: 1) does 0-CFA use significantly more time and space than the algorithms and techniques in the present invention for large benchmarks? 2) is the potential extra precision of 0-CFA worth the increased cost? And 3) when used in a compiler for devirtualization of monomorphic calls, does 0-CFA give significantly better speedups than the algorithms and techniques in the present invention? Answers may well shed more light on which algorithm to choose. Perhaps 0-CFA needs to be a fair bit better than the other algorithms before it becomes tempting to implement the program transformation that enables 0-CFA for Java bytecodes.

While adding Hindley-Milner polymorphism seems not to be worthwhile, initial experiments have been conducted with the use of data-polymorphism.18,27 The idea is well known: treat each distinct allocation site as a separate class, and keep the fields in these artificial classes distinct.18,27 Similarly, distinct sets may be used when methods are invoked on objects of the same type but allocated at different sites. Data-polymorphism has the potential of significantly increasing the cost (more elements have to be propagated, and the number of distinct sets may increase as well). However, accuracy may improve as well because unrelated instantiations of the same type are kept separate, thereby leading to a more precise analysis of their fields.

Pseudo-Code for the XTA Algorithm

The set constraints described in the present invention can be interpreted by “solvers” such as BANE which was developed at the University of California at Berkeley. The following pseudo-code, which is understandable to one of average skill in the art, is given as one possible embodiment of the XTA algorithm described in the present invention. It is important to note that the pseudo-code although complete, many pragmatic issues such as direct method calls, library usage, and class initializers are not addressed and can be found in several prior art references. Moreover, the pseudo-code describes a “naive” implementation in which no attempt has been made to make the code efficient e.g., by avoiding redundant propagations.

The following conventions are used for the data structures used in the pseudo-code:

FIG. 9 is a high-level block diagram 900 of the procedures used in the Pseudo-code, according to the present invention. The compute Call Graph Pseudo-Code as described below contains eight procedures. In this exemplary embodiment, the pseudo-code is arranged into eight procedures as follows:

---------------------------------------------------------------------
PROCEDURE computeCallGraph(Program P)
BEGIN
CALL initialize();
WHILE (MethodsToScan is not empty OR
MethodPairs is not empty OR
Field Pairs is not empty) DO
FOR each method M in MethodsToScan DO
CALL scanMethod(M);
remove M from MethodsToScan;
END FOR
FOR each pair <M, T> in MethodPairs DO
CALL propagateToMethod(M, T);
remove <M, T> from MethodPairs;
END FOR
FOR each pair <F, T> in FieldPairs DO
CALL propagateToField(F, T);
remove <F, T> from FieldPairs;
END FOR
END WHILE
RETURN <Nodes, Edges>;
END PROCEDURE
---------------------------------------------------------------------
// Initializations.
PROCEDURE initialize()
BEGIN
let main be the main procedure in P;
mark main “Reached”;
Nodes := {main };
Edges := {};
MethodsToScan = { main };
Method Pairs = {};
FieldPairs = {};
FOR each method M DO
Types(M) = {};
END FOR
FOR each field F DO
Types(F) = {};
END FOR
END PROCEDURE
---------------------------------------------------------------------
// Scan the method's body to detect read/written fields,
// call sites, and allocation sites.
PROCEDURE scanMethod(method M)
BEGIN
determine the set ReadFields(M) of fields read by M;
determine the set WrittenFields(M) of fields written by M;
determine the set VirtualCallSites(M) of virtual call sites in M;
FOR each allocation site “new T” in M DO
IF (<M, T> does not occur in MethodPairs) THEN
add <M, T> to MethodPairs;
END IF
END FOR
FOR each field F in ReadFields(M) DO
FOR each type T in Types(F) DO
IF (<M, T> does not occur in MethodPairs) THEN
add <M, T> to MethodPairs;
END IF
END FOR
END FOR
END PROCEDURE
---------------------------------------------------------------------
// Propagate type T to method M.
// Propagate the type to:
// - fields written by M,
// - methods called by M,
// - methods that call M
// as appropriate.
PROCEDURE propagateToMethod(method M, type T)
BEGIN
add T to Types(M);
CALL resolveVirtualMethodCalls(M, T);
FOR each field F in Written Fields(M) DO
let X be the type of F;
let S be the set of types in Types(M) that are subtypes of X;
FOR each type U in S DO
IF (U not in TYPES(F) and <F, U> not in FieldPairs) THEN
add <F, U> to FieldPairs;
END IF
END FOR
END FOR
FOR each edge <CallSite, Callee> in Edges
such that CallSite occurs in M DO
let Caller be the method containing CallSite;
CALL propagateToCallee(Callee, Types(Caller));
END FOR
FOR each edge <CallSite, M> in Edges DO
let Caller be the method containing CallSite;
CALL propagateToCaller(Caller, M, Types(M));
END FOR
END PROCEDURE
---------------------------------------------------------------------
// Determine the methods that can be reached from a
// given method's virtual call sites, for a given type.
// Add the appropriate call graph edges.
// Add any newly reached methods to the worklist.
PROCEDURE resolveVirtualMethodCalls(method M, type T)
BEGIN
FOR each site S in VirtualCallSites(M) DO
let M′ be the method referenced at S;
IF (T is a subtype of the class in which M′ occurs) THEN
let M“ = StaticLookup(T, M′);
IF (M“ is not marked “Reached”) THEN
mark M“ “Reached”;
add M“ to Nodes;
add M“ to MethodsToScan;
END IF
IF (Edges does not contain an edge S->M“) THEN
add edge S->M“ to Edges;
propagateToCallee(M, M“, Types(M));
propagateToCaller(M, M“, Types(M“));
END IF
END FOR
END PROCEDURE
---------------------------------------------------------------------
// Propagate from caller to callee, filter using parameter types
// Propagate from caller to callee, filter using “this” pointer:
// types for which StaticLookup(T, M′) == M′ holds.
PROCEDURE propagateToCallee(method Callee, typeset V)
FOR each type T in V DO
IF (T is a subtype of the type of a parameter of Callee) THEN
IF ((T does not occur in Types(Callee) AND
(<Callee, T> does not occur in Method Pairs)) THEN
add <Callee, T> to MethodPairs;
END IF
END IF
END FOR
FOR each type T in V DO
IF (StaticLookup(T, Callee) == Callee) THEN
IF ((T does not occur in Types(Callee) AND
(<Callee, T> does not occur in Method Pairs)) THEN
add <Callee, T> to MethodPairs;
END IF
END IF
END FOR
END PROCEDURE
---------------------------------------------------------------------
// Propagate from callee to caller, filter using return type
PROCEDURE propagateToCaller(method Caller, method Callee,
typeset V)
BEGIN
FOR each type T in V DO
IF (T is a subtype of the return type of Callee) THEN
IF ((T does not occur in Types(Caller) AND
(<Caller, T> does not occur in MethodPairs)) THEN
add <Caller, T> to MethodPairs;
END IF
END IF
END FOR
END PROCEDURE
---------------------------------------------------------------------
PROCEDURE propagateToField(field F, type T)
BEGIN
add T to Types(F);
FOR each method M such that F occurs in ReadFields(M) DO
IF (T does not occur in Types(M) AND
<M, T> does not occur in MethodPairs) THEN
add <M, T> to MethodPairs;
END IF
END FOR
END PROCEDURE
---------------------------------------------------------------------

Discussion of Hardware and Software Implementation Options

The present invention, as would be known to one of ordinary skill in the art could be produced in hardware or software, or in a combination of hardware and software. The system, or method, according to the inventive principles as disclosed in connection with the preferred embodiment, may be produced in a single computer system having separate elements or means for performing the individual functions or steps described or claimed or one or more elements or means combining the performance of any of the functions or steps disclosed or claimed, or may be arranged in a distributed computer system, interconnected by any suitable means as would be known by one of ordinary skill in art.

According to the inventive principles as disclosed in connection with the preferred embodiment, the invention and the inventive principles are not limited to any particular kind of computer system but may be used with any general purpose computer, as would be known to one of ordinary skill in the art, arranged to perform the functions described and the method steps described. The operations of such a computer, as described above, may be according to a computer program contained on a medium for use in the operation or control of the computer, as would be known to one of ordinary skill in the art. The computer medium which may be used to hold or contain the computer program product, may be a fixture of the computer such as an embedded memory or may be on a transportable medium such as a disk, as would be known to one of ordinary skill in the art.

The invention is not limited to any particular computer program or logic or language, or instruction but may be practiced with any such suitable program, logic or language, or instructions as would be known to one of ordinary skill in the art. Without limiting the principles of the disclosed invention any such computing system can include, inter alia, at least a computer readable medium allowing a computer to read data, instructions, messages or message packets, and other computer readable information from the computer readable medium. The computer readable medium may include non-volatile memory, such as ROM, Flash memory, floppy disk, Disk drive memory, CD-ROM, and other permanent storage. Additionally, a computer readable medium may include, for example, volatile storage such as RAM, buffers, cache memory, and network circuits.

Furthermore, the computer readable medium may include computer readable information in a transitory state medium such as a network link and/or a network interface, including a wired network or a wireless network, that allow a computer to read such computer readable information.

The following references are a list of references that have been referenced throughout the present invention. These references are hereby incorporated by reference in their entirety.

Although a specific embodiment of the invention has been disclosed. It will be understood by those having skill in the art that changes can be made to this specific embodiment without departing from the spirit and scope of the invention. The scope of the invention is not to be restricted, therefore, to the specific embodiment, and it is intended that the appended claims cover any and all such applications, modifications, and embodiments within the scope of the present invention.

Tip, Frank, Palsberg, Jens

Patent Priority Assignee Title
10540255, Oct 31 2017 Oracle International Corporation Staged refinement for static analysis
11360877, Sep 14 2020 International Business Machines Corporation Forming microservices from monolithic applications
7213243, Sep 30 2002 Fujitsu Limited Program optimization by unused data item
7272828, Nov 27 2002 Intel Corporation Software object type identification
7426716, Jul 11 2003 Board of Regents The University of Texas System Recovery and representation of object interaction in an object oriented program
7661095, Apr 14 2005 VALTRUS INNOVATIONS LIMITED System and method to build a callgraph for functions with multiple entry points
7669193, Sep 25 2003 Lantronix, Inc. Program transformation using flow-sensitive type constraint analysis
7936868, Sep 24 2007 Consistacom, Inc. Method and system for automatically generating flow charts of call flow programs
8132150, Feb 20 2008 International Business Machines Corporation Automatic customization of classes
8141049, Mar 14 2007 NEC Corporation System and method for scalable flow and context-sensitive pointer alias analysis
8141063, Aug 30 2007 International Business Machines Corporation Static analysis of reachable methods and fields in object-oriented applications using object instantiation
8291395, Mar 31 2006 Apple Inc. Fast function call dispatching
8856765, Dec 14 2010 International Business Machines Corporation Analyzing a pointer in an analysis target program or a partial program
9697034, Aug 07 2015 FUTUREWEI TECHNOLOGIES, INC Offloading probabilistic computations in data analytics applications
Patent Priority Assignee Title
5428793, Nov 13 1989 Hewlett-Packard Company Method and apparatus for compiling computer programs with interproceduural register allocation
5671419, Jun 15 1995 International Business Machines Corporation Interprocedural data-flow analysis that supports recursion while only performing one flow-sensitive analysis of each procedure
5933640, Feb 26 1997 Hewlett Packard Enterprise Development LP Method for analyzing and presenting test execution flows of programs
5963740, Mar 01 1994 HEWLETT-PACKARD DEVELOPMENT COMPANY, L P System for monitoring computer system performance
6041179, Oct 03 1996 IBM Corporation Object oriented dispatch optimization
6240500, Jun 08 1998 HEWLETT-PACKARD DEVELOPMENT COMPANY, L P Method for dynamically placing procedures of a program in a memory
6282707, Feb 16 1998 NEC Electronics Corporation Program transformation method and program transformation system
6546551, Sep 28 1999 International Business Machines Corporation Method for accurately extracting library-based object-oriented applications
6654951, Dec 14 1998 International Business Machines Corporation Removal of unreachable methods in object-oriented applications based on program interface analysis
6665865, Apr 27 2000 Microsoft Technology Licensing, LLC Equivalence class based synchronization optimization
20020010911,
20030172135,
///
Executed onAssignorAssigneeConveyanceFrameReelDoc
Mar 22 2001TIP, FRANKInternational Business Machines CorporationASSIGNMENT OF ASSIGNORS INTEREST SEE DOCUMENT FOR DETAILS 0117270526 pdf
Mar 28 2001PALSBERG, JENSInternational Business Machines CorporationASSIGNMENT OF ASSIGNORS INTEREST SEE DOCUMENT FOR DETAILS 0117270526 pdf
Mar 30 2001International Business Machines Corporation(assignment on the face of the patent)
Date Maintenance Fee Events
Sep 13 2005ASPN: Payor Number Assigned.
Sep 28 2009REM: Maintenance Fee Reminder Mailed.
Feb 21 2010EXP: Patent Expired for Failure to Pay Maintenance Fees.


Date Maintenance Schedule
Feb 21 20094 years fee payment window open
Aug 21 20096 months grace period start (w surcharge)
Feb 21 2010patent expiry (for year 4)
Feb 21 20122 years to revive unintentionally abandoned end. (for year 4)
Feb 21 20138 years fee payment window open
Aug 21 20136 months grace period start (w surcharge)
Feb 21 2014patent expiry (for year 8)
Feb 21 20162 years to revive unintentionally abandoned end. (for year 8)
Feb 21 201712 years fee payment window open
Aug 21 20176 months grace period start (w surcharge)
Feb 21 2018patent expiry (for year 12)
Feb 21 20202 years to revive unintentionally abandoned end. (for year 12)