Slicing Object-Oriented Software1
Loren D. Larsen2 and Mary Jean Harrold
Department of Computer Science
Clemson, SC 29634-1906
fllarsen, [email protected]
We describe the construction of system dependence graphs for object-oriented software on which efficient slicing algorithms can be applied. We construct these system dependence graphs for individual classes, groups of interacting classes, and complete object-oriented programs. These system dependence graphs consist of a class dependence graph for each class in the system and a procedure dependence graph that represents a calling program. For an incomplete system consisting of a single class or a number of interacting classes, we construct a procedure dependence graph that simulates all possible calls to public methods in the class. For a complete system, we construct a procedure dependence graph from the main program in the system. Using these system dependence graphs, we show how to compute slices for the individual classes, groups of interacting classes or complete programs. Our slicing algorithm is based on an interprocedural slicing algorithm that utilizes graph reachability. One advantage of our approach is that the system dependence graphs can be constructed incrementally because representations of classes can be reused many times. Another advantage of our approach is that slices can be computed for incomplete object-oriented programs such as classes or class libraries. We present our results for C++, but our techniques apply to other statically typed object-oriented languages such as Ada-95.
Program slicing has many applications such as debugging, code understanding, program testing, reverse engineering, software metrics and automatic parallelization [7, 8, 9, 15, 18, 20, 26, 32]. Weiser  defined a slice with respect to a slicing criterion that consists of a program point p and a subset of program variables V . His slices were executable programs that were constructed by removing zero or more statements from the original program. He presented algorithms, which use dataflow analysis on control flow graphs, to compute intraprocedural and interprocedural slices. Ottenstein and Ottenstein  defined a slicing criterion to consist of a program point p and a variable v, which is defined or used at p. They compute a slice, using a graph reachability algorithm on a program dependence graph, consisting of all statements and predicates of the program that may affect the value of v at p. Horwitz, Reps and Binkley  also use dependence graphs to compute slices. They developed an interprocedural program representation, the system dependence graph, and a two-pass graph reachability slicing algorithm that uses the system dependence graph. Their two-pass algorithm computes more precise interprocedural slices than previous algorithms because it uses summary information at call sites to account for the calling context of called procedures. Researchers have considered ways to extend language features represented by system dependence graphs. These language features include arrays [3, 17, 24, 27], reference parameters , pointers [11, 17, 21] and non-structured control flow [2, 4, 12]. Researchers have also proposed variations of dependence graphs that facilitate finer-grained slices [20, 23], and have developed techniques to perform slicing on optimized code .3
1This work was partially supported by grants from Microsoft, Inc. and Data General Corp., and by NSF under Grants
CCR-9109531 and CCR-9357811 to Clemson University.
2Current address: IBM Corporation, Research Triangle Park, North Carolina.
3For a survey of program slicing techniques see reference .