sofya.graphs.cfg
Class CFGBuilder

java.lang.Object
  extended by sofya.graphs.cfg.CFGBuilder
All Implemented Interfaces:
SConstants

public class CFGBuilder
extends java.lang.Object
implements SConstants

This class constructs and caches intraprocedural control flow graphs for Java methods. It provides for the ability to apply transformations to the control flow graphs after the basic construction algorithm has completed.

Version:
06/09/2006
Author:
Alex Kinneer

Nested Class Summary
static class CFGBuilder.LoadException
          Exception which indicates that an error has occurred during an attempt to load and parse a Java class file for graph construction.
 
Nested classes/interfaces inherited from interface sofya.base.SConstants
SConstants.BlockLabel, SConstants.BlockObjectType, SConstants.BlockSubType, SConstants.BlockType, SConstants.BranchObjectType, SConstants.BranchType, SConstants.EDObjectType, SConstants.TraceObjectType
 
Field Summary
static java.lang.String[] excludePackages
          List of packages that are excluded when identifying call blocks (invocations of methods on classes in these packages are not marked as call blocks).
 
Fields inherited from interface sofya.base.SConstants
DEFAULT_PORT, INST_COMPATIBLE, INST_OLD_UNSUPPORTED, INST_OPT_NORMAL, INST_OPT_SEQUENCE, SIG_CHKALIVE, SIG_ECHO
 
Constructor Summary
protected CFGBuilder()
          Convenience constructor used internally.
  CFGBuilder(org.apache.bcel.classfile.JavaClass javaClass)
          Creates a CFG builder to build graphs for the class represented by the given BCEL JavaClass.
  CFGBuilder(java.util.List classList)
          Constructs a CFG builder.
 
Method Summary
 void addTransformer(CFGTransformer t)
          Adds a transformation to be applied to control flow graphs after construction.
 java.util.Iterator buildAllCFG()
          Builds the control flow graphs for every method in the class and returns an iterator over the collection.
 CFG buildCFG(MethodSignature signature)
          Builds a control flow graph for a method and adds it to the cache, locating the method by signature.
 CFG buildCFG(java.lang.String methodName, org.apache.bcel.generic.Type returnType, org.apache.bcel.generic.Type[] argumentTypes)
          Builds a control flow graph for a method and adds it to the cache, using name and signature elements to locate the method.
 java.util.Iterator getAllCFG()
          Retrieves the control flow graphs for every method in the class and returns an iterator over the collection.
 CFG getCFG(MethodSignature signature)
          Gets a control flow graph for a method from the cache by signature.
 CFG getCFG(java.lang.String methodName, org.apache.bcel.generic.Type returnType, org.apache.bcel.generic.Type[] argumentTypes)
          Attempts to retrieve a control flow graph for a method from the cache, using name and signature elements to locate the method.
 java.lang.String getLoadedClass()
          Gets the name of the class currently loaded in the CFG builder.
 int getMethodCount()
          Get the number of methods in the class.
 MethodSignature[] getMethods()
          Gets the signatures of all the methods found in the currently loaded class.
 void loadClass(org.apache.bcel.classfile.JavaClass clazz)
          Loads a class previously parsed by BCEL.
 void loadClass(java.lang.String className)
          Loads a new class on which to operate.
 void loadClass(java.lang.String className, java.io.InputStream source)
          Loads a new class from a given stream.
protected  void parseClass(java.lang.String className, java.io.InputStream source)
          Parses the class.
 void removeTransformer(CFGTransformer t)
          Removes a transformation from the transformation list.
 void setClassList(java.util.List classes)
          Sets the list of classes comprising the program for which graphs are being built (if applicable).
 void writeCFFile(boolean rebuild, java.lang.String tag)
          Writes the control flow file for the current class.
 void writeMapFile(boolean rebuild, java.lang.String tag)
          Writes the map file for the current class.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

excludePackages

public static final java.lang.String[] excludePackages
List of packages that are excluded when identifying call blocks (invocations of methods on classes in these packages are not marked as call blocks). Wildcard matching is automatic (e.g. an exclusion for "java" matches all classes whose package name begins with "java.").

Constructor Detail

CFGBuilder

protected CFGBuilder()
Convenience constructor used internally.


CFGBuilder

public CFGBuilder(java.util.List classList)
           throws java.io.IOException
Constructs a CFG builder.

Parameters:
classList - List of classes for which CFG construction is expected to be requested.
Throws:
java.io.IOException - If certain I/O operations required by the type inference module fail.

CFGBuilder

public CFGBuilder(org.apache.bcel.classfile.JavaClass javaClass)
           throws BadFileFormatException,
                  java.io.IOException
Creates a CFG builder to build graphs for the class represented by the given BCEL JavaClass.

Note: Interprocedural type inference algorithms will be severely crippled by the use of this constructor.

Parameters:
javaClass - BCEL representation of an already parsed Java class.
Throws:
BadFileFormatException - If the specified class is an interface.
java.io.IOException - If certain I/O operations required by the type inference module fail.
Method Detail

addTransformer

public void addTransformer(CFGTransformer t)
Adds a transformation to be applied to control flow graphs after construction.

Parameters:
t - Transformation to be added to the list of transformations applied by this CFG builder.

removeTransformer

public void removeTransformer(CFGTransformer t)
Removes a transformation from the transformation list.

Parameters:
t - Transformation to be removed from the list of transformations applied by this CFG builder.

loadClass

public void loadClass(java.lang.String className)
               throws CFGBuilder.LoadException
Loads a new class on which to operate.

Parameters:
className - Name of the class for which graphs are to be created.
Throws:
CFGBuilder.LoadException - If the specified class cannot be found, read, parsed, or is an interface.

loadClass

public void loadClass(java.lang.String className,
                      java.io.InputStream source)
               throws CFGBuilder.LoadException
Loads a new class from a given stream.

Parameters:
className - Name of the class for which graphs are to be managed.
source - Stream from which the class should be read.
Throws:
CFGBuilder.LoadException - If the specified class cannot be found, read, parsed, or is an interface.

loadClass

public void loadClass(org.apache.bcel.classfile.JavaClass clazz)
               throws CFGBuilder.LoadException
Loads a class previously parsed by BCEL.

Parameters:
clazz - BCEL parsed representation of the class to be loaded.
Throws:
CFGBuilder.LoadException - If the given class represents an interface.

parseClass

protected void parseClass(java.lang.String className,
                          java.io.InputStream source)
                   throws CFGBuilder.LoadException
Parses the class.

Uses BCEL to parse the class file.

Parameters:
className - Name of the class to be parsed.
source - Stream from which the class should be parsed. May be null, in which case this method will attempt to load the class from the classpath or the filesystem (in that order).
Throws:
CFGBuilder.LoadException - If the specified class cannot be found, read, parsed, or is an interface.

setClassList

public void setClassList(java.util.List classes)
Sets the list of classes comprising the program for which graphs are being built (if applicable).

Parameters:
classes - List of classes constituting the program for which CFG construction is being performed. The list may contain a single class, though this will cause some type inference algorithms to perform poorly.

getLoadedClass

public java.lang.String getLoadedClass()
Gets the name of the class currently loaded in the CFG builder.

Returns:
Name of the class currently loaded in the CFG builder.

getMethodCount

public int getMethodCount()
Get the number of methods in the class.

Returns:
The number of methods found in the class.

getMethods

public MethodSignature[] getMethods()
Gets the signatures of all the methods found in the currently loaded class.

Returns:
An array of method signatures for each method found in the current class.

buildCFG

public CFG buildCFG(MethodSignature signature)
             throws java.lang.IllegalArgumentException,
                    MethodNotFoundException,
                    TypeInferenceException,
                    TransformationException
Builds a control flow graph for a method and adds it to the cache, locating the method by signature.

Parameters:
signature - Signature of the method for which a control flow graph is to be built.
Returns:
The control flow graph for the specified method.
Throws:
java.lang.IllegalArgumentException - If the requested method is native or abstract.
MethodNotFoundException - If no method matching the specified signature can be found.
TypeInferenceException - If type inference fails during CFG construction for any reason.
TransformationException - If any transformation applied to the CFG during construction fails.

buildCFG

public CFG buildCFG(java.lang.String methodName,
                    org.apache.bcel.generic.Type returnType,
                    org.apache.bcel.generic.Type[] argumentTypes)
             throws java.lang.IllegalArgumentException,
                    MethodNotFoundException,
                    TypeInferenceException,
                    TransformationException
Builds a control flow graph for a method and adds it to the cache, using name and signature elements to locate the method.

Parameters:
methodName - Name of the method for which to build a graph.
returnType - Return type of the method.
argumentTypes - The types of the arguments to the method.
Returns:
The resulting control flow graph.
Throws:
java.lang.IllegalArgumentException - If the requested method is native or abstract.
MethodNotFoundException - If no method matching the specified name and signature can be found.
TypeInferenceException - If type inference fails during CFG construction for any reason.
TransformationException - If any transformation applied to the CFG during construction fails.

getCFG

public CFG getCFG(MethodSignature signature)
           throws java.lang.IllegalArgumentException,
                  MethodNotFoundException,
                  TypeInferenceException,
                  TransformationException
Gets a control flow graph for a method from the cache by signature. If the graph does not exist it is built and added to the cache.

Parameters:
signature - Signature of the method for which the control flow graph is to be retrieved.
Returns:
The requested control flow graph.
Throws:
java.lang.IllegalArgumentException - If the requested method is native or abstract.
MethodNotFoundException - If no method matching the specified signature can be found.
TypeInferenceException - If type inference fails during CFG construction for any reason.
TransformationException - If any transformation applied to the CFG during construction fails.

getCFG

public CFG getCFG(java.lang.String methodName,
                  org.apache.bcel.generic.Type returnType,
                  org.apache.bcel.generic.Type[] argumentTypes)
           throws java.lang.IllegalArgumentException,
                  MethodNotFoundException,
                  TypeInferenceException,
                  TransformationException
Attempts to retrieve a control flow graph for a method from the cache, using name and signature elements to locate the method. If the graph can't be found, it will be built and added to the cache.

Parameters:
methodName - Name of the method for which to build a graph.
returnType - Return type of the method.
argumentTypes - The types of the arguments to the method.
Returns:
The resulting control flow graph.
Throws:
java.lang.IllegalArgumentException - If the requested method is native or abstract.
MethodNotFoundException - If no method matching the specified name and signature can be found.
TypeInferenceException - If the CFG must be built and type inference fails during that process for any reason.
TransformationException - If any transformation applied to the CFG during construction fails.

buildAllCFG

public java.util.Iterator buildAllCFG()
                               throws TypeInferenceException,
                                      TransformationException
Builds the control flow graphs for every method in the class and returns an iterator over the collection. This refreshes the cache for every method in the class.

An iterator is returned because some graphs may be cached to disk and thus can't be returned directly in-memory.

Returns:
An iterator over the collection of control flow graphs for every method in the class.
Throws:
TypeInferenceException - If type inference fails for any reason during construction of a CFG.
TransformationException - If any transformation applied to a constructed CFG fails.

getAllCFG

public java.util.Iterator getAllCFG()
                             throws TypeInferenceException,
                                    TransformationException
Retrieves the control flow graphs for every method in the class and returns an iterator over the collection. This will cause control flow graphs to be built for every method that hasn't yet had a control flow graph built, but will retrieve existing control flow graphs from the cache.

An iterator is returned because some graphs may be cached to disk and thus can't be returned directly in-memory.

Returns:
An iterator over the collection of control flow graphs for every method in the class.
Throws:
TypeInferenceException - If a CFG must be built and type inference fails during that process for any reason.
TransformationException - If a CFG must be built and any transformation applied to it fails.

writeCFFile

public void writeCFFile(boolean rebuild,
                        java.lang.String tag)
                 throws TypeInferenceException,
                        TransformationException,
                        java.io.IOException
Writes the control flow file for the current class.

Parameters:
rebuild - If true, every control flow graph is rebuilt, otherwise graphs are only built for those methods which don't yet have a control flow graph in the cache.
Throws:
java.io.IOException - If there is an error creating or writing the .cf file.
TypeInferenceException - If type inference fails for any reason during construction of a CFG.
TransformationException

writeMapFile

public void writeMapFile(boolean rebuild,
                         java.lang.String tag)
                  throws TypeInferenceException,
                         TransformationException,
                         java.io.IOException
Writes the map file for the current class.

Parameters:
rebuild - If true, every control flow graph is rebuilt, otherwise graphs are only built for those methods which don't yet have a control flow graph in the cache.
Throws:
java.io.IOException - If there is an error creating or writing the .map file.
TypeInferenceException - If type inference fails for any reason during construction of a CFG.
TransformationException