Implementing CHA
The code for CHA is in the
following 5 files
- ChaMain.java: Top-level control. Uses a Loader object to load the
JIMPLE in memory, and then invokes a ChaAnalysis object to do the actual call
graph construction.
- Loader.java: Loads JIMPLE from disk to memory.
- ChaAnalysis: Does the bulk of the analysis work, using the
algorithm presented in class
- Hierarchy: Stores some data structures related to the class
hierarchy; used by ChaAnalysis and ChaWriter.
- ChaWriter: Writes output files; used by ChaAnalysis.
Understand the code
Print the code in ChaMain, ChaAnalysis, and
Hierarchy. Read it very carefully and make sure you understand what is
going on. There is not need to read the code for Loader and for ChaWriter. Here
is some relevant information:
- Soot uses its own class soot.SootClass to represent JIMPLE classes and
interfaces that are read from disk. For each JIMPLE class or interface X,
there is a unique SootClass object corresponding to X. Similarly, for each
JIMPLE method m, there is a unique object of class soot.SootMethod that
represents m. For example, for p1, there is a SootClass object representing
class A, and three SootMethod objects representing the three methods in A.
- SootClass has several important methods:
- boolean declaresMethod(String s): returns true if this class
contains a method whose signature (name + parameter types) and return type
match string s. For example, to determine whether a SootClass contains
"main", one should invoke declaresMethod("void main(java.lang.String[])").
Note that fully qualified names should be given for the classes — that is,
the names should contain all package prefixes. For example, if you tried to
look up "void main(String[])", Soot would complain because it would assume
that there is some class String (not part of any package) that you are
referring to, as opposed to the library class java.lang.String which is in
package java.lang.
- SootMethod getMethod(String s): if declaresMethod(s) is true,
getMethod(s) returns the corresponding SootMethod object; otherwise it
fails.
- boolean hasSuperclass(): true if the corresponding JIMPLE class
has a superclass. In reality, this is always true except for
java.lang.Object (the root of the class hierarchy). If the SootClass object
represents an interface, the superclass is considered to be java.lang.Object
(this conforms to the language specification).
- SootClass getSuperclass(): if hasSuperclass() is true,
getSuperclass() returns the SootClass object representing the superclass;
otherwise it fails.
- Chain getInterfaces(): returns a list of SootClass objects that
represent all interfaces implemented directly by the class — e.g. if we have
"class A implements X, Y", the list will contain two SootClass objects
representing X and Y. Chain is a Soot utility class that implements
interface java.util.Collection;
its elements can be accessed using the standard Java iteration mechanism
(with iterator())
- SootMethod has several relevant methods:
- SootClass getDeclaringClass(): returns the enclosing class
- String getSubSignature(): returns a string representing the
return value + the signature of the method (e.g. "void m(int)"). If
reference variable x points to a SootMethod object,
x.getDeclaringClass().getMethod(x.getSubSignature()) returns that same
SootMethod object.
- There are several other Soot classes used by the analysis (e.g.
soot.jimple.InvokeExpr). The relevant aspects of these classes should be
obvious from the code.
Implement CHA
There are 4 places where you need to add your own code:
- Method traverse in Hierarchy
- Method virtualDispatch in Hierarchy
- Method addToWorklist in ChaAnalysis
- Method analyze in ChaAnalysis
The comments in the code should
provide enough detail about the necessary modifications. If you have any
problems understanding the code or figuring out what needs to be done, let me
know. I'd suggest the following strategy: implement and test each of the 4
changes separately. First implement "traverse", and then "virtualDispatch".
Check the output files (for the 7 data programs) before and after each change
and make sure that your code does the right thing.