sofya.ed.semantic
Class SemanticInstrumentor

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

public class SemanticInstrumentor
extends Instrumentor

The instrumentor for semantic event dispatching. This class compiles an event specification for the SemanticEventDispatcher and uses the specification to insert probes necessary to enable the SemanticEventDispatcher to produce all of those events.

This class can be used to instrument for semantic event dispatch by compiling an event specification given by a module description file. It is also used to instrument for atomicity checking.

Note that the instrumentation should only ever be applied once, or the behavior of the tools is undefined. If the parameters of the instrumentation need to be changed (e.g. as by a change to the module description), the system should be recompiled first and then instrumented again.

Version:
06/09/2006
Author:
Alex Kinneer

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 static java.lang.String arrFieldPrefix
          Name prefix for probe fields used to record array element events.
protected static java.lang.String arrIdxFieldName
          Name of the probe field used to record array event element indices.
protected static java.lang.String arrRefRdFieldName
          Name of the probe field used to record array element read events.
protected static java.lang.String arrRefWrFieldName
          Name of the probe field used to record array element write events.
protected  boolean autoBoundaryEvents
          Flag which specifies whether boundary events are to be raised (execution entering or leaving the module through method calls).
protected static java.lang.String codeFieldName
          Name of the probe field used to record event type codes.
protected  int curInterceptID
          Next available ID for an interceptor, to avoid name collisions.
protected  SemanticEventData dataFile
          Data file generated for the SemanticEventDispatcher.
protected  EventSpecification eventSpec
          Compiled representation of the event specification.
protected  org.apache.bcel.generic.CodeExceptionGen[] exceptionHandlers
          Exception handlers associated with the method currently being instrumented.
protected  int excHandlerVar
          Local variable index used to hold exception objects in inserted exception handlers.
protected static java.lang.String flagFieldName
          Special flag field that may be used to receive very limited commands back from the event dispatcher.
protected  java.util.Map interceptorCache
          Caches previously created interceptor methods, so that they can be used by multiple calls to the same intercepted method.
protected  gnu.trove.TObjectIntHashMap lineNumbers
          Maps instruction handles to source code line numbers, these are pre-loaded from the method line number table before beginning instrumentation of the method.
protected static java.lang.String loadFieldName
          Name of the probe field used to record class prepare events.
protected  java.lang.String methodName
          Name of the method currently being instrumented.
protected  java.util.Set moduleClasses
          Set of classes for which observables are included by default.
protected static java.lang.String monaFieldName
          Name of the probe field used to record monitor acquisition events.
protected static java.lang.String moncFieldName
          Name of the probe field used to record monitor contention events.
protected static java.lang.String monFieldPrefix
          Name prefix for probe fields used to record monitor events.
protected static java.lang.String monprFieldName
          Name of the probe field used to record monitor-to-be-released events.
protected static java.lang.String monrFieldName
          Name of the probe field used to record monitor released events.
protected  org.apache.bcel.generic.InstructionHandle origEnd
          Stores the last instruction of an un-instrumented method; used to properly target various instrumentation instructions.
protected  org.apache.bcel.generic.InstructionHandle origStart
          Stores the first instruction of an un-instrumented method; used to ensure legal insertion of certain instrumentation.
static java.lang.String PROBE_CLASS
           
protected  java.util.Set systemClasses
          Set of classes comprising the entire system.
protected static java.lang.String typeFieldName
          Name of the probe field used to record object types for relevant events, such as exception related events.
 
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
SemanticInstrumentor(SemanticEventData edd)
          Creates a new module instrumentor.
 
Method Summary
 void addExitProbes(org.apache.bcel.generic.MethodGen mg, org.apache.bcel.generic.InstructionList il, org.apache.bcel.generic.InstructionHandle syntheticHandler)
          Adds method exit probes to a method; handles all types of methods including static initializers.
 SConstants.TraceObjectType getObjectType()
          Reports the type of program entity traced by this instrumentor to satisfy the Instrumentor contract.
protected  java.lang.String getProbeClassName()
          Gets the name of the class referenced by probes inserted by this instrumentor.
protected  void init(int port)
          Initializes the instrumentor, making it ready to instrument methods in the class.
protected  org.apache.bcel.classfile.Method instrument(org.apache.bcel.classfile.Method m, int methodIndex, boolean insertStarter)
          Instruments a method.
 boolean isAutoBoundaryEventsEnabled()
          Reports whether the instrumentor is set to insert probes to automatically observe module boundary events (calls which cause execution to exit the module).
static boolean isNative(org.apache.bcel.generic.InvokeInstruction call, org.apache.bcel.generic.ConstantPoolGen cpg)
          Reports whether a static method is implemented in native code.
static void main(java.lang.String[] argv)
          Entry point for the instrumentor.
 boolean parseTypeCodes(java.lang.String typeCodes)
          Returns true always, since there is no type codes argument to this instrumentor.
 void setAutoBoundaryEventsEnabled(boolean enable)
          Specifies whether the instrumentor is to insert probes to automatically observe module boundary events (calls which cause execution to exit the module).
 void setTypeFlags(int flags)
          Does nothing, since there is no type codes argument to this instrumentor.
 void writeClass(java.io.OutputStream dest)
          Writes the binary instrumented class data to a stream.
 
Methods inherited from class sofya.ed.Instrumentor
addDefaultHandler, cacheHandlerStarts, generateClass, getClassName, getInstMode, getLastInstrumented, getMethodCount, getMethodName, getMethodSignature, getPort, getQualifiedName, getTypeFlags, hasMain, hasStaticInit, insertFinisher, insertProbeFinishCall, insertProbeStartCall, insertStarter, instrument, instrumentAll, loadBlockRefs, loadClass, loadClass, parseClass, parseCommandLine, reloadClass, reloadMethod, setInstMode, setPort
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

methodName

protected java.lang.String methodName
Name of the method currently being instrumented.


eventSpec

protected EventSpecification eventSpec
Compiled representation of the event specification.


dataFile

protected SemanticEventData dataFile
Data file generated for the SemanticEventDispatcher.


systemClasses

protected java.util.Set systemClasses
Set of classes comprising the entire system.


moduleClasses

protected java.util.Set moduleClasses
Set of classes for which observables are included by default.


autoBoundaryEvents

protected boolean autoBoundaryEvents
Flag which specifies whether boundary events are to be raised (execution entering or leaving the module through method calls).


origStart

protected org.apache.bcel.generic.InstructionHandle origStart
Stores the first instruction of an un-instrumented method; used to ensure legal insertion of certain instrumentation.


origEnd

protected org.apache.bcel.generic.InstructionHandle origEnd
Stores the last instruction of an un-instrumented method; used to properly target various instrumentation instructions.


excHandlerVar

protected int excHandlerVar
Local variable index used to hold exception objects in inserted exception handlers.


exceptionHandlers

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


lineNumbers

protected gnu.trove.TObjectIntHashMap lineNumbers
Maps instruction handles to source code line numbers, these are pre-loaded from the method line number table before beginning instrumentation of the method.


interceptorCache

protected java.util.Map interceptorCache
Caches previously created interceptor methods, so that they can be used by multiple calls to the same intercepted method.


curInterceptID

protected int curInterceptID
Next available ID for an interceptor, to avoid name collisions.


PROBE_CLASS

public static final java.lang.String PROBE_CLASS
See Also:
Constant Field Values

codeFieldName

protected static final java.lang.String codeFieldName
Name of the probe field used to record event type codes. A field by this name is inserted in instrumented classes, thus it is constructed in a way that is intended to avoid a naming collision with any existing fields.

See Also:
Constant Field Values

loadFieldName

protected static final java.lang.String loadFieldName
Name of the probe field used to record class prepare events.

See Also:
Constant Field Values

typeFieldName

protected static final java.lang.String typeFieldName
Name of the probe field used to record object types for relevant events, such as exception related events.

See Also:
Constant Field Values

monFieldPrefix

protected static final java.lang.String monFieldPrefix
Name prefix for probe fields used to record monitor events.

See Also:
Constant Field Values

moncFieldName

protected static final java.lang.String moncFieldName
Name of the probe field used to record monitor contention events.

See Also:
Constant Field Values

monaFieldName

protected static final java.lang.String monaFieldName
Name of the probe field used to record monitor acquisition events.

See Also:
Constant Field Values

monprFieldName

protected static final java.lang.String monprFieldName
Name of the probe field used to record monitor-to-be-released events.

See Also:
Constant Field Values

monrFieldName

protected static final java.lang.String monrFieldName
Name of the probe field used to record monitor released events.

See Also:
Constant Field Values

arrFieldPrefix

protected static final java.lang.String arrFieldPrefix
Name prefix for probe fields used to record array element events.

See Also:
Constant Field Values

arrRefRdFieldName

protected static final java.lang.String arrRefRdFieldName
Name of the probe field used to record array element read events.

See Also:
Constant Field Values

arrRefWrFieldName

protected static final java.lang.String arrRefWrFieldName
Name of the probe field used to record array element write events.

See Also:
Constant Field Values

arrIdxFieldName

protected static final java.lang.String arrIdxFieldName
Name of the probe field used to record array event element indices.

See Also:
Constant Field Values

flagFieldName

protected static final java.lang.String flagFieldName
Special flag field that may be used to receive very limited commands back from the event dispatcher.

See Also:
Constant Field Values
Constructor Detail

SemanticInstrumentor

public SemanticInstrumentor(SemanticEventData edd)
Creates a new module instrumentor.

Parameters:
edd - Event dispatch data object to which this instrumentor will store event dispatch information.
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

getProbeClassName

protected java.lang.String getProbeClassName()
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.

isAutoBoundaryEventsEnabled

public boolean isAutoBoundaryEventsEnabled()
Reports whether the instrumentor is set to insert probes to automatically observe module boundary events (calls which cause execution to exit the module).

Returns:
true if calls to methods outside of the module are to generate events regardless of the module description, false otherwise.

setAutoBoundaryEventsEnabled

public void setAutoBoundaryEventsEnabled(boolean enable)
Specifies whether the instrumentor is to insert probes to automatically observe module boundary events (calls which cause execution to exit the module).

Parameters:
enable - true if calls to methods outside of the module are to be instrumented to generate events regardless of the module description, false otherwise.

instrument

protected org.apache.bcel.classfile.Method instrument(org.apache.bcel.classfile.Method m,
                                                      int methodIndex,
                                                      boolean insertStarter)
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 - Ignored.
Returns:
The instrumented method. If the method is native, abstract, or has no body, it is returned unchanged.

addExitProbes

public void addExitProbes(org.apache.bcel.generic.MethodGen mg,
                          org.apache.bcel.generic.InstructionList il,
                          org.apache.bcel.generic.InstructionHandle syntheticHandler)
Adds method exit probes to a method; handles all types of methods including static initializers.

Parameters:
mg - BCEL handle to the method for which to insert method exit probes.
il - Instruction list for the method to be instrumented.
syntheticHandler - Handle to the last instruction of any synthetic catch-all handler previously inserted; used to guarantee an exit event even on exceptional exit. May be null, in which case the handler will be created.

writeClass

public void writeClass(java.io.OutputStream dest)
                throws java.io.IOException
Description copied from class: Instrumentor
Writes the binary instrumented class data to a stream.

The class data written constitutes a valid Java class file. In other words, if the output stream is a file, the resulting file will be a valid class file containing any instrumentation that was applied.

Overrides:
writeClass in class Instrumentor
Parameters:
dest - Output stream to which class is to be written.
Throws:
java.io.IOException - If there is an error writing to the stream.

getObjectType

public SConstants.TraceObjectType getObjectType()
Reports the type of program entity traced by this instrumentor to satisfy the Instrumentor contract. Not used in any meaningful way by this instrumentor.

Specified by:
getObjectType in class Instrumentor
Returns:
Integer code indicating that this instrumentor instruments program entities related to semantic event dispatch.

parseTypeCodes

public boolean parseTypeCodes(java.lang.String typeCodes)
Returns true always, since there is no type codes argument to this instrumentor.

Specified by:
parseTypeCodes in class Instrumentor
Parameters:
typeCodes - Ignored.
Returns:
true, always.

setTypeFlags

public void setTypeFlags(int flags)
Does nothing, since there is no type codes argument to this instrumentor. Instrumentor control is instead defined by the module description file.

Specified by:
setTypeFlags in class Instrumentor
Parameters:
flags - Ignored.

isNative

public static final boolean isNative(org.apache.bcel.generic.InvokeInstruction call,
                                     org.apache.bcel.generic.ConstantPoolGen cpg)
                              throws java.lang.ClassNotFoundException
Reports whether a static method is implemented in native code. The answer will not be reliable in the presence of runtime reflective class loading.

The result of this method cannot be trusted if called on a non-static method! No static guarantee can be made that a virtual method will always call a native implementation, since it may depend on the receiver type of the object.

Parameters:
call - Invoke instruction for the call that is to be checked for native implementation.
cpg - Constant pool for the class in which the call resides.
Returns:
true if the static method binds to a native implementation.
Throws:
java.lang.ClassNotFoundException - If a class needed to determine the result cannot be found on the classpath.

main

public static void main(java.lang.String[] argv)
Entry point for the instrumentor.