sofya.ed.structural
Class BranchInstrumentor

java.lang.Object
  extended by sofya.ed.Instrumentor
      extended by sofya.ed.structural.BranchInstrumentor
All Implemented Interfaces:
org.apache.bcel.generic.InstructionConstants, SConstants

public class BranchInstrumentor
extends Instrumentor

The Sofya branch edge instrumentor. Classes instrumented by this instrumentor can be executed by event dispatchers using branch processing strategies.

Version:
06/29/2006
Author:
Alex Kinneer
See Also:
cfInstrumentor

Nested Class Summary
 
Nested classes/interfaces inherited from interface org.apache.bcel.generic.InstructionConstants
org.apache.bcel.generic.InstructionConstants.Clinit
 
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
protected  org.apache.bcel.generic.CodeExceptionGen[] exceptionHandlers
          Exception handlers associated with the method currently being instrumented.
 
Fields inherited from class sofya.ed.Instrumentor
arrayVarref, blockCount, classGraphs, classHasMain, classHasStaticInit, classIsDispatcher, classIsSocketProbe, className, cpg, excExitBooleanVar, fullClassName, handlerStarts, iFactory, instClassRef, instMode, javaClass, javaClassFile, lastInstrumented, methodCFG, methodEntryMethodref, methods, mSignature, port, starterInserted, startMethodref, tag, targetJUnit, traceMethodref, typeFlags, useDefaultPort
 
Fields inherited from interface org.apache.bcel.generic.InstructionConstants
AALOAD, AASTORE, ACONST_NULL, ALOAD_0, ALOAD_1, ALOAD_2, ARETURN, ARRAYLENGTH, ASTORE_0, ASTORE_1, ASTORE_2, ATHROW, BALOAD, BASTORE, bla, CALOAD, CASTORE, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DMUL, DNEG, DREM, DRETURN, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FMUL, FNEG, FREM, FRETURN, FSUB, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD_0, ILOAD_1, ILOAD_2, IMUL, INEG, INSTRUCTIONS, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE_0, ISTORE_1, ISTORE_2, ISUB, IUSHR, IXOR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDIV, LMUL, LNEG, LOR, LREM, LRETURN, LSHL, LSHR, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, NOP, POP, POP2, RETURN, SALOAD, SASTORE, SWAP, THIS
 
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 BranchInstrumentor()
          Protected default constructor, to prevent unsafe instances of the instrumentor from being created.
  BranchInstrumentor(java.lang.String className)
          Standard constructor, constructs instrumentor for the specified class using the default port.
  BranchInstrumentor(java.lang.String[] argv)
          See Instrumentor.Instrumentor(String[]).
  BranchInstrumentor(java.lang.String className, int port)
          Standard constructor, constructs instrumentor for the specified class using the given port.
  BranchInstrumentor(java.lang.String className, int port, int instMode)
          Standard constructor, constructs instrumentor for the specified class using the given port and activating the specified mode of instrumentation.
 
Method Summary
protected  void addSummaryThrowHandler(org.apache.bcel.generic.MethodGen mg, org.apache.bcel.generic.InstructionList il, org.apache.bcel.generic.InstructionHandle regStart, org.apache.bcel.generic.InstructionHandle regEnd, int exceptionVar)
          Attaches an intercepting exception handler to the method which marks the summary exceptional exit branch to signify exceptional exit from the method caused by any type of unchecked exception for which precise control flow modeling is too costly (such as operator and array-related exceptions).
protected  SConstants.TraceObjectType getObjectType()
          Reports that this instrumentor operates on branch edges.
protected  java.lang.String getProbeClassName()
          Gets the name of the class referenced by probes inserted by this instrumentor.
 int getTypeFlags()
          The branch instrumentor does not filter instrumentation based on object types, so this method throws an exception.
protected  void init(int port)
          Initializes the instrumentor, making it ready to instrument methods in the class.
protected  org.apache.bcel.generic.CodeExceptionGen insertCallHandler(Block b, org.apache.bcel.generic.MethodGen mg, org.apache.bcel.generic.InstructionList il, org.apache.bcel.generic.InstructionHandle ih, int localVar)
          Inserts an intercepting exception handler to detect and record exceptions propagated by called methods, including those which are rethrown.
protected  void insertProbe(Block node, org.apache.bcel.generic.InstructionList il, org.apache.bcel.generic.InstructionHandle ih)
          Inserts the bytecode sequence to witness the execution of one edge out of a set of branch edges.
protected  void insertThrowerBranches(Block b, org.apache.bcel.generic.InstructionList il, org.apache.bcel.generic.InstructionHandle ih, int localVar, SConstants.BranchType edgeType)
          Inserts probe to properly witness a branch edge executed as a result of exceptional control flow.
protected  org.apache.bcel.generic.InstructionHandle insertUnaryProbe(int branchID, org.apache.bcel.generic.InstructionList il, org.apache.bcel.generic.InstructionHandle insert_ih, int edgeType)
          Inserts the basic bytecode sequence to witness a single branch edge.
protected  org.apache.bcel.classfile.Method instrument(org.apache.bcel.classfile.Method m, int methodIndex, boolean insertStarter)
          Instruments a method.
protected  boolean parseTypeCodes(java.lang.String typeCodes)
          The branch instrumentor does not filter instrumentation based on object types, so this method prints a warning and takes no action.
 void setTypeFlags(int typeCodes)
          The branch instrumentor does not filter instrumentation based on object types, so this method throws an exception.
 
Methods inherited from class sofya.ed.Instrumentor
addDefaultHandler, cacheHandlerStarts, generateClass, getClassName, getInstMode, getLastInstrumented, getMethodCount, getMethodName, getMethodSignature, getPort, getQualifiedName, hasMain, hasStaticInit, insertFinisher, insertProbeFinishCall, insertProbeStartCall, insertStarter, instrument, instrumentAll, loadBlockRefs, loadClass, loadClass, parseClass, parseCommandLine, reloadClass, reloadMethod, setInstMode, setPort, writeClass
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

exceptionHandlers

protected org.apache.bcel.generic.CodeExceptionGen[] exceptionHandlers
Exception handlers associated with the method currently being instrumented.

Constructor Detail

BranchInstrumentor

protected BranchInstrumentor()
Protected default constructor, to prevent unsafe instances of the instrumentor from being created.


BranchInstrumentor

public BranchInstrumentor(java.lang.String[] argv)
                   throws java.lang.IllegalArgumentException,
                          java.io.IOException,
                          java.lang.ClassFormatError,
                          java.lang.Exception
See Instrumentor.Instrumentor(String[]).

Throws:
java.lang.IllegalArgumentException
java.io.IOException
java.lang.ClassFormatError
java.lang.Exception

BranchInstrumentor

public BranchInstrumentor(java.lang.String className)
                   throws BadFileFormatException,
                          java.lang.IllegalArgumentException,
                          java.io.IOException,
                          java.lang.ClassFormatError,
                          java.lang.Exception
Standard constructor, constructs instrumentor for the specified class using the default port.

Parameters:
className - Name of the class to be instrumented.
Throws:
java.lang.IllegalArgumentException - If required parameters are missing, invalid parameters are encountered, or data required for optional parameters is missing.
BadFileFormatException - If the class is an interface.
java.io.IOException - If there is an error reading the class file.
java.lang.ClassFormatError - If the class file cannot be parsed.
java.lang.Exception - If any other error is raised attempting to parse the class.

BranchInstrumentor

public BranchInstrumentor(java.lang.String className,
                          int port)
                   throws BadFileFormatException,
                          java.lang.IllegalArgumentException,
                          java.io.IOException,
                          java.lang.ClassFormatError,
                          java.lang.Exception
Standard constructor, constructs instrumentor for the specified class using the given port.

Parameters:
className - Name of the class to be instrumented.
port - Port to which instrumentation should be set. The valid range is 1024 to 65535.
Throws:
java.lang.IllegalArgumentException - If required parameters are missing, invalid parameters are encountered, or data required for optional parameters is missing.
BadFileFormatException - If the class is an interface.
java.io.IOException - If there is an error reading the class file.
java.lang.ClassFormatError - If the class file cannot be parsed.
java.lang.Exception - If any other error is raised attempting to parse the class.

BranchInstrumentor

public BranchInstrumentor(java.lang.String className,
                          int port,
                          int instMode)
                   throws BadFileFormatException,
                          java.lang.IllegalArgumentException,
                          java.io.IOException,
                          java.lang.ClassFormatError,
                          java.lang.Exception
Standard constructor, constructs instrumentor for the specified class using the given port and activating the specified mode of instrumentation.

Parameters:
className - Name of the class to be instrumented.
port - Port to which instrumentation should be set. The valid range is 1024 to 65535.
instMode - Integer flag indicating the form of instrumentation to be inserted. Acceptable values are the following:
Throws:
java.lang.IllegalArgumentException - If required parameters are missing, invalid parameters are encountered, or data required for optional parameters is missing.
BadFileFormatException - If the class is an interface.
java.io.IOException - If there is an error reading the class file.
java.lang.ClassFormatError - If the class file cannot be parsed.
java.lang.Exception - If any other error is raised attempting to parse the class.
Method Detail

init

protected void init(int port)
             throws java.io.IOException
Description copied from class: Instrumentor
Initializes the instrumentor, making it ready to instrument methods in the class.

Analyzes the class and sets various flags used to control instrumentation. Determines if the subject is a filter class or SocketProbe. Determines the default port or checks that the port number is in range if one is specified. Adds the instrumentation method references to the class constant pool. Determines if the class has a static initializer and/or main method to control where to insert the call to SocketProbe.start.

Overrides:
init in class Instrumentor
Parameters:
port - Port which is to be used for instrumentation. If a negative number is supplied, the default port is selected. Otherwise, the valid range for this parameter is 1024 to 65535.
Throws:
java.io.IOException

parseTypeCodes

protected boolean parseTypeCodes(java.lang.String typeCodes)
The branch instrumentor does not filter instrumentation based on object types, so this method prints a warning and takes no action.

Specified by:
parseTypeCodes in class Instrumentor
Parameters:
typeCodes - Parameter read from command-line, including the leading dash.
Returns:
true, always.

getTypeFlags

public int getTypeFlags()
The branch instrumentor does not filter instrumentation based on object types, so this method throws an exception.

Overrides:
getTypeFlags in class Instrumentor
Returns:
Bit mask controlling what types of objects are instrumented.
Throws:
java.lang.UnsupportedOperationException - Always.

setTypeFlags

public void setTypeFlags(int typeCodes)
The branch instrumentor does not filter instrumentation based on object types, so this method throws an exception.

Specified by:
setTypeFlags in class Instrumentor
Parameters:
typeCodes - Bit mask representing the types of objects to be instrumented.
Throws:
java.lang.UnsupportedOperationException - Always.

getObjectType

protected SConstants.TraceObjectType getObjectType()
Reports that this instrumentor operates on branch edges.

Specified by:
getObjectType in class Instrumentor
Returns:
The type code for the branch edge entity.

getProbeClassName

protected java.lang.String getProbeClassName()
Description copied from class: Instrumentor
Gets the name of the class referenced by probes inserted by this instrumentor.

Specified by:
getProbeClassName in class Instrumentor
Returns:
The name of the probe class used by this instrumentor.

instrument

protected org.apache.bcel.classfile.Method instrument(org.apache.bcel.classfile.Method m,
                                                      int methodIndex,
                                                      boolean insertStarter)
Description copied from class: Instrumentor
Instruments a method.

Performs the actual instrumentation and update of the method in the class.

Specified by:
instrument in class Instrumentor
Parameters:
m - Method to be instrumented.
methodIndex - Index to the method in the class method array.
insertStarter - If true, force the instrumentor to insert a call to SocketProbe.start at the beginning of this method, otherwise it will be determined automatically whether it should be inserted.
Returns:
The instrumented method. If the method is native, abstract, or has no body, it is returned unchanged.

insertUnaryProbe

protected org.apache.bcel.generic.InstructionHandle insertUnaryProbe(int branchID,
                                                                     org.apache.bcel.generic.InstructionList il,
                                                                     org.apache.bcel.generic.InstructionHandle insert_ih,
                                                                     int edgeType)
Inserts the basic bytecode sequence to witness a single branch edge.

This method is used to insert a probe where only a single branch ID is possible. This includes the "entry" branch, the <normal> branch from calls (the other probes are inserted in the attached exception handler), and the "summary throw" branch.

The exact bytecode that is inserted will depend on the instrumentation mode.

Parameters:
branchID - Branch ID witnessed by the probe.
il - BCEL instruction list into which the probe is to be inserted.
insert_ih - Instruction handle at which the probe is to be inserted in il.
edgeType - The type of the branch edge witnessed by the probe.
Returns:
The instruction handle of the first instruction in the inserted probe.

insertProbe

protected void insertProbe(Block node,
                           org.apache.bcel.generic.InstructionList il,
                           org.apache.bcel.generic.InstructionHandle ih)
Inserts the bytecode sequence to witness the execution of one edge out of a set of branch edges.

The exact bytecode that is inserted will depend on the instrumentation mode.

Parameters:
node - Block at which the branching control flow occurs.
il - Instruction list for the method into which the probe is to be inserted.
ih - Instruction handle before which the probe is to be inserted.

insertThrowerBranches

protected void insertThrowerBranches(Block b,
                                     org.apache.bcel.generic.InstructionList il,
                                     org.apache.bcel.generic.InstructionHandle ih,
                                     int localVar,
                                     SConstants.BranchType edgeType)
Inserts probe to properly witness a branch edge executed as a result of exceptional control flow.

The method constructs the bytecode equivalent of an if-elseif-...-elseif which detects the class of exception using instanceof and pushes the correct branch ID onto the stack. A single action to record/transmit the branch ID is at the end, followed by the original throw instruction. This mechanism is also used indirectly for call nodes, which calls this method to create the contents of the intercept handler that is attached to the invoke instruction.

Parameters:
b - Block containing the throw instruction for which the probe is to be inserted.
il - The instruction list of the method, into which the probe is to be inserted.
ih - Instruction in front of which the probe is to be inserted - this should normally be an ATHROW instruction.
localVar - Index of the local variable which will be used for temporary storage of the exception object.
edgeType - The type of the branch edges witnessed by the probe.

insertCallHandler

protected org.apache.bcel.generic.CodeExceptionGen insertCallHandler(Block b,
                                                                     org.apache.bcel.generic.MethodGen mg,
                                                                     org.apache.bcel.generic.InstructionList il,
                                                                     org.apache.bcel.generic.InstructionHandle ih,
                                                                     int localVar)
Inserts an intercepting exception handler to detect and record exceptions propagated by called methods, including those which are rethrown.

A 'catch-all' exception handler (equivalent to those created for finally blocks) is attached to the call instruction. The catch block for the handler contains probes to witness any of the exceptional branches. This method also inserts the probe to witness the normal return from the method. Note that on the normal (non- exceptional) path of execution, the handler is never invoked and execution continues as usual.

Parameters:
b - Block containing the call to which the handler is being attached.
mg - The BCEL mutable representation of the method, required to manipulate the exception handlers associated with the method.
il - Bytecode instruction list for the method being instrumented.
ih - Handle to the call instruction.
localVar - Index of the local variable used for temporary storage of the exception object in the inserted handler.

addSummaryThrowHandler

protected void addSummaryThrowHandler(org.apache.bcel.generic.MethodGen mg,
                                      org.apache.bcel.generic.InstructionList il,
                                      org.apache.bcel.generic.InstructionHandle regStart,
                                      org.apache.bcel.generic.InstructionHandle regEnd,
                                      int exceptionVar)
Attaches an intercepting exception handler to the method which marks the summary exceptional exit branch to signify exceptional exit from the method caused by any type of unchecked exception for which precise control flow modeling is too costly (such as operator and array-related exceptions).

Parameters:
mg - The BCEL mutable representation of the method, required to manipulate the exception handlers associated with the method.
il - The instruction list of the method, into which the exceptional exit probe code will be inserted. This parameter is also required since the instruction list is in a working state and will not necessarily have been committed to the MethodGen object provided in the mg parameter.
regStart - Original start instruction of the method (before any modifications by the instrumentor). It cannot be the very first instruction of the method, because by the time this method is called, all of the instrumentation should have been inserted. Some modes of instrumentation require an array reference which is retrieved by the call invoked on method entry. If the handler watch region encloses that call, then the reference will be considered out of scope of the exception handler and it won't be able to use it to mark the edge.
regEnd - Original end instruction of the method. Used to avoid interactions with other handlers added by the instrumentor.
exceptionVar - Index of the local variable which will be used for temporary storage of the exception object in the handler.