org.jboss.byteman.agent.adapter.cfg
Class CFG

java.lang.Object
  extended by org.jboss.byteman.agent.adapter.cfg.CFG

public class CFG
extends java.lang.Object

A control flow graph (cfg) for use by trigger method adapters.

A trigger method adapter is required to notify the CFG each time an instruction or label is visited and each time a try catch block is notified. It is also required to notify the CFG when trigger coe generartion begins and ends. The cfg allows the trigger method adapter to identify whether or not trigger code is within the scope of one or more synchronized blocks, allowing it to protect the trigger call with try catch handlers which ensure that any open monitor enters are rounded off with a corresponding monitor exit.

A cfg is constructed dynamically as the code is visited in order to enable trigger insertion to be performed during a single pass of the bytecode. See RuleTriggerMethodAdapter for an example of how the methods provided by this class are invoked during visiting of the method byte code. Methods provided for driving CFG construction include:

The cfg maintains the current instruction sequence for the method in encoded form as it is being generated. The cfg models both the linear instruction sequence and the directed graph of control flow through that sequence. It splits the instruction stream at control flow branch points, grouping instructions into basic blocks. A successor link relation between blocks retains the linear instruction sequence. Control flow links between basic blocks define the graph structure. The cfg correlates labels with i) blocks and ii) instruction offsets within those blocks as the labels are visited during bytecode visiting. It also tracks the locations within blocks of try catch regions and their handlers and of monitor enter and exit instructions.

The lock propagation algorithm employed to track the extent of monitor enter/exit pairs and try/catch blocks is the most complex aspect of this implementation, mainly because it has to be done in a single pass. This means that the end location of a try catch block or the location of the (one or more) monitor exit(s) associated with a monitor enter may not be known when a trigger point is reached. This algorithm is described below in detail. First an explanation of the CFG organization is provided.

Control flow graph model

The bytecode sequence is segmented into basic blocks at control flow branches ensuring there is no explicit control flow internal to a block. The only way normal control can flow from one block to another is via a switch/goto/branch instruction occuring at the end of the block. So, basic blocks are the nodes of the CFG and the links in the graph identify these control flow transitions.

Normal control flow linkage is explicitly represented in the blocks as a list containing the labels of the target blocks. Labels are used rather than handles on the block themselves so that forward links to blocks which have not yet been generated can be modelled. Labels are resolved to the relevant block and instruction index as they are visited during walking of the bytecode.

The outgoing control flow link count can be obtained by calling method BBlock.nOuts(). The label of the block to which control is transferred can be identified by calling method BBlock.nthOut(int). Note that valid link indices run from 1 to nOuts() (see below). Once a label has been visited it can be resolved to a CodeLocation by calling method CFG#getLocation(org.objectweb.asm.Label). The returned value identifies both a block and an instruction offset in the block.

Several caveats apply to this simple picture. Firstly, blocks ending in return or throw have no control flow -- they pass control back to the caller rather than to another basic block. So, the count returned by BBlock.nOuts() will be 0 for such blocks.

Secondly, all blocks except the last have a distinguished link which identifies the block successor link relationship. The successor block can be obtained by supplying value 0 as argument to method BBlock.nthOut(int). This link is additional to any control flow links and it is not included in the count returned by BBlock.nOuts(). Note that where there is a control flow link to the next block in line (e.g. where the block ends in an ifXX instruction) the label employed for the distinguished 0 link will also appear in the set of control flow links (as link 1 in the case of an ifXX instruction).

The final caveat is that this graph model does not identify control flow which occurs as a consequence of generated exceptions.

Exceptional Control Flow

Exception control flow is modelled independently from normal flow because it relates to a segment of the instruction sequence rather than individual instructions. A specific exception flow is associated with a each try catch block and the target of the flow is the start of the handler block. The cfg maintains a list of TryCatchDetails which identify the location of the try/catch start, its end and the associated handler start location. Once again labels are used so as to allow modelling of forward references to code locations which have not yet been generated.

Note that handler start labels always refer to a code location which is at the start of a basic block. Start and end labels for a given try/catch block may refer to code locations offset into their containing basic block and possibly in distinct blocks.

Methods #tryCatchStart(org.objectweb.asm.Label), #tryCatchEnd(org.objectweb.asm.Label) and #tryCatchHandlerStart(org.objectweb.asm.Label) can be called to determine whether a given label identifies, respectively, the start of a try catch block, the end of a try catch block or the start of a handler block. Methods #tryCatchStartDetails(org.objectweb.asm.Label) #tryCatchEndDetails(org.objectweb.asm.Label), and #tryCatchHandlerStartDetails(org.objectweb.asm.Label) can be used to retrieve the associated TryCatchDetails information.

Label Resolution

The cfg relies upon its adapter client to notify it whenever a label is visited during a walk of the bytecode. This allows it to associate labels with the basic blocks and instruction offsets within those blocks. The cfg provides method CFG#getBlock(org.objectweb.asm.Label) to resolve the primary label for a block (i.e. the one supplied as argument to a split call) to the associated block. It also provides method CFG#getBlockInstructionIdx(org.objectweb.asm.Label) to resolve a label to a CodeLocation i.e. block and instruction index within a block. Both methods return null if the label has not yet been visited.

Method getContains(BBlock) is also provided to obtain a list of all labels contained within a specific block. There may be more than one label which resolves to a location within a specific block. For example, the handler start label associated with a try/catch handler is contained in the handler block at offset 0 but is never the primary label for the block. Iteration over the contained set is used internally in the cfg to resolve equivalent labels.

lock propagation algorithm

The cfg tracks the occurence of monitor enter and monitor exit instructions as they are encountered during the bytecode walk. Note that the relationship between enter and exit instructions is 1 to many. For any given monitor enter there are one or more exits associated with the normal control flow path and zero or more alternative exits associated with exception control flow paths. The association between monitor entry and monitor exit instructions is made available via methods getPairedEnter(CodeLocation), and getPairedExit(CodeLocation, BBlock) 9note that a given enter will never have more than one exit in any given block).

The cfg associates monitor enters and exits with their enclosing block, allowing it to identify the start and/or end of synchronized regions within a specific block. This information can be propagated along control flow links to identify outstanding monitor enters at any point in a given control flow path. Whenever a block is created it is associated with a set of open enter instructions i.e. enter instructions occurring along all control flow paths to the block for which no corresponding exit has been executed.

Note that we still need to worry about nested try/catch regions shadowing outer try/catch handlers with a more specific exception type e.g. when a try region with a catch-all handler type is embedded within a try region with a specific exception type or, less commonly, when the inner block employs a super type of the outer block. In these cases exception flow from the inner region cannot reach the handler for the outer region. This means we must dispense with propagation of open monitor enters to the outer region since they will be closed by the inner handler. TODO -- implement this last check


Field Summary
private  java.util.Map<Label,BBlock> blocks
          a mapping from the start label of a basic block to the associated block
private  java.util.Map<BBlock,FanOut> contains
          a map identifying the containment relationship between a basic block and labels which identify instructions located within the block - the first entry is the block label itself
private static int CONTAINS
          flag value passed to request a check for a containment and returned to notify a containment
private  BBlock current
          the current basic block
private  java.util.List<TryCatchDetails> currentTryCatchStarts
          a list of all try catch blocks which are started but not ended.
static Type EARLY_RETURN_EXCEPTION_TYPE
          Type identifying return exceptions thrown by runtime
static java.lang.String EARLY_RETURN_EXCEPTION_TYPE_NAME
          name of type identifying return exceptions thrown by runtime
private  BBlock entry
          the label of the first basic block in the code
static Type EXECUTE_EXCEPTION_TYPE
          Type identifying execute exceptions thrown by runtime
static java.lang.String EXECUTE_EXCEPTION_TYPE_NAME
          name of type identifying execute exceptions thrown by runtime
private  java.util.Map<CodeLocation,CodeLocation> inverseMonitorPairs
          an inverse map from each monitor exit instruction to the monitor enter insructions it closes.
private  java.util.Map<Label,CodeLocation> labelLocations
          a mapping from each label to its enclosing basic block and instruction offset
private  TriggerDetails latestTrigger
          details of the last trigger section encountered set when a trigger start label is notified
private  java.lang.String methodName
          the name of the method for which this is a CFG
private  java.util.Map<CodeLocation,java.util.List<CodeLocation>> monitorPairs
          a map from monitor enter instructions to the monitor exit insructions which close them.
private  java.util.List<java.lang.String> names
          a list of names employed in the bytecode
private  int nextIdx
          a counter used to number bblocks in code order
private  java.util.Map<Label,java.util.List<CodeLocation>> openMonitorEnters
          a map from block labels to any unclosed monitor enter instructions outstanding when the block is entered.
private static int OVERLAPS
          flag value passed to request a check for an overlap and returned to notify an overlap
static Type THROW_EXCEPTION_TYPE
          Type identifying throw exceptions thrown by runtime
static java.lang.String THROW_EXCEPTION_TYPE_NAME
          name of type identifying throw exceptions thrown by runtime
private  java.util.Map<Label,TriggerDetails> triggerEnds
          a map from labels which identify the end of a code injection sequence to details of the labels which locate the sequence and its exception handlers
private  java.util.Map<Label,TriggerDetails> triggerStarts
          a map from labels which identify the start of a code injection sequence to details of the labels which locate the sequence and its exception handlers
private  java.util.Map<Label,java.util.List<TryCatchDetails>> tryCatchEnds
          a map from try catch block end labels to the corresponding try catch block details -- the value is a list because the code reader will reuse the same label when two try catch blocks end at the same bytecode
private  java.util.Map<Label,java.util.List<TryCatchDetails>> tryCatchHandlers
          a map from try catch block handler labels to the corresponding try catch block details -- the value is a list because the code reader will reuse the same label when two handler blocks start at the same bytecode
private  java.util.Map<Label,java.util.List<TryCatchDetails>> tryCatchStarts
          a map from try catch block start labels to the corresponding try catch block details -- the value is a list because the code reader will reuse teh same label when two try catch blocks start at the same bytecode
private static int UNKNOWN
          flag value returned to notify that a containment cannot yet be computed
 
Constructor Summary
CFG(java.lang.String methodName, Label start)
          construct a CFG labelling the initial block with a given label
 
Method Summary
 void add(int instruction)
          aopend an instruction to the current block
 void add(int instruction, int operand)
          append an instruction with one operand to the current block
 void add(int instruction, int[] operands)
          append an operand with more than two operands ot the current block
 void add(int instruction, int operand1, int operand2)
          append an instruction with two operands to the current block
 void add(int instruction, java.lang.String name)
          append an instruction with a String operand to the current block
 void add(int instruction, java.lang.String name, int dims)
          append a multiarray create instruction to the current block
 void add(int instruction, java.lang.String owner, java.lang.String name, java.lang.String desc)
          append a field or method instruction with 3 String operands to the current block
private  void addContains(BBlock block, Label label)
          add a label to the list of labels contained in a given block
(package private)  void addMonitorPair(CodeLocation enter, CodeLocation exit)
          pair a monitor enter instruction with an associated monitor exit instructions
private  void carryForward()
          forward details of open monitor and try catch block locations from the current block to its reachable labels.
private  int computeContainment(CodeLocation tryStart, CodeLocation tryEnd, CodeLocation enter, CodeLocation exit, int flags)
          compute whether the the region defined by a given enter and exit location pair overlaps or is contained within the region defined by a try start and end location pair when both regions ar erestricted to the current block
 BBlock getBlock(Label label)
          return the block containing a label if known
 int getBlockInstructionIdx(Label label)
          return the index of the label in its enclosing block's instruction sequence of -1 if the label has not yet been visited.
 FanOut getContains(BBlock block)
          return a link object listing all the labels contained in a given block
 CodeLocation getLocation(Label label)
          return the location of the label if known or null if it has not yet been reached.
 java.lang.String getName(int nameIdx)
           
 java.util.List<CodeLocation> getOpenMonitorEnters(Label label)
          retrieve the list of monitor enter locations open at the start of a given block
 java.util.Iterator<CodeLocation> getOpenMonitors(TriggerDetails triggerDetails)
          retrieve the list of monitor enter locations associated with a trigger block.
 CodeLocation getPairedEnter(CodeLocation exit)
          locate the monitor enter instruction associated with a given monitor exit
private  CodeLocation getPairedExit(CodeLocation enter, BBlock block)
          locate a monitor exit instruction in block associated with a given monitor enter
 int getSavedMonitorIdx(CodeLocation open)
          return the index of the local var at which this monitorenter saved its lock object
 boolean hasLocation(Label label)
          test whether the location of a label is known yet
 boolean inBytemanHandler()
          check if the current block is a byteman-generated handler i.e.
 boolean inBytemanTrigger()
          check if the current block is a byteman-generated trigger section.
 boolean inRethrowHandler()
          return true if the current block is a rethrow handler i.e.
 CodeLocation nextLocation()
          return a location which will identify the next instruction added to the current block
 CodeLocation setLocation(Label label)
          set the location of a label to the next instruction offset in the current block
 void split(Label newStart)
          split the graph at a control-flow dead-end using the label provided to identify the new current block.
 void split(Label newStart, Label out)
          split the graph at a control-flow goto point using the labels provided to identify the new current block and the goto target.
 void split(Label newStart, Label out, Label out2)
          split the graph at a control-flow if branch point using the labels provided to identify the new current block the if branch target and the else branch target.
 void split(Label newStart, Label dflt, Label[] labels)
          split the graph at a control-flow switch branch point using the labels provided to identify the new current block, the switch case default branch target and the rest of the switch case branch targets.
 java.lang.String toString()
          generate a string representation of the CFG
 java.util.Iterator<TriggerDetails> triggerDetails()
          return an iterator ovver all known trigger detailsd
 boolean triggerEnd(Label label)
          test if a label marks the end of a trigger block
 TriggerDetails triggerEndDetails(Label label)
          return the list of details of try catch blocks which end at this label
 boolean triggerStart(Label label)
          test if a label marks the start of a trigger block
 TriggerDetails triggerStartDetails(Label label)
          return details of any trigger block which starts at this label
 boolean tryCatchEnd(Label label)
          test if a label marks the end of a try catch block
 java.util.List<TryCatchDetails> tryCatchEndDetails(Label label)
          return the list of details of try catch blocks which end at this label
 boolean tryCatchHandlerStart(Label label)
          test if a label marks the start of the handler for a try catch block
 java.util.List<TryCatchDetails> tryCatchHandlerStartDetails(Label label)
          return the list of details of try catch blocks whose handler startsend at this label
 boolean tryCatchStart(Label label)
          test if a label marks the start of a try catch block
 java.util.List<TryCatchDetails> tryCatchStartDetails(Label label)
          return the list of details of try catch blocks which start at this label
private  boolean tryStartMayContainEnter(CodeLocation tryStart, CodeLocation enter)
          check whether the instructions exposed by a monitor enter may be contained within the scope of a tryStart.
 void visitEnd()
           
 void visitLabel(Label label)
          notify the CFG that a label has been visited by the method visitor and hence its position will now be resolved
 void visitMaxs()
          this can be called when the code generator call visiMaxs but it does nothing just now
 void visitTriggerEnd(Label label)
          notify the CFG that a label which represents the end of a trigger injection sequence has just been visited by the method visitor.
 void visitTriggerStart(Label label)
          notify the CFG that a label which represents the start of a trigger injection sequence has just been visited by the method visitor.
 void visitTryCatchBlock(Label start, Label end, Label handler, java.lang.String type)
          notify the CFG of the location of a try catch block.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

EXECUTE_EXCEPTION_TYPE

public static final Type EXECUTE_EXCEPTION_TYPE
Type identifying execute exceptions thrown by runtime


EARLY_RETURN_EXCEPTION_TYPE

public static final Type EARLY_RETURN_EXCEPTION_TYPE
Type identifying return exceptions thrown by runtime


THROW_EXCEPTION_TYPE

public static final Type THROW_EXCEPTION_TYPE
Type identifying throw exceptions thrown by runtime


EXECUTE_EXCEPTION_TYPE_NAME

public static final java.lang.String EXECUTE_EXCEPTION_TYPE_NAME
name of type identifying execute exceptions thrown by runtime


EARLY_RETURN_EXCEPTION_TYPE_NAME

public static final java.lang.String EARLY_RETURN_EXCEPTION_TYPE_NAME
name of type identifying return exceptions thrown by runtime


THROW_EXCEPTION_TYPE_NAME

public static final java.lang.String THROW_EXCEPTION_TYPE_NAME
name of type identifying throw exceptions thrown by runtime


methodName

private java.lang.String methodName
the name of the method for which this is a CFG


entry

private BBlock entry
the label of the first basic block in the code


current

private BBlock current
the current basic block


nextIdx

private int nextIdx
a counter used to number bblocks in code order


blocks

private java.util.Map<Label,BBlock> blocks
a mapping from the start label of a basic block to the associated block


labelLocations

private java.util.Map<Label,CodeLocation> labelLocations
a mapping from each label to its enclosing basic block and instruction offset


contains

private java.util.Map<BBlock,FanOut> contains
a map identifying the containment relationship between a basic block and labels which identify instructions located within the block - the first entry is the block label itself


names

private java.util.List<java.lang.String> names
a list of names employed in the bytecode


triggerStarts

private java.util.Map<Label,TriggerDetails> triggerStarts
a map from labels which identify the start of a code injection sequence to details of the labels which locate the sequence and its exception handlers


triggerEnds

private java.util.Map<Label,TriggerDetails> triggerEnds
a map from labels which identify the end of a code injection sequence to details of the labels which locate the sequence and its exception handlers


latestTrigger

private TriggerDetails latestTrigger
details of the last trigger section encountered set when a trigger start label is notified


tryCatchStarts

private java.util.Map<Label,java.util.List<TryCatchDetails>> tryCatchStarts
a map from try catch block start labels to the corresponding try catch block details -- the value is a list because the code reader will reuse teh same label when two try catch blocks start at the same bytecode


tryCatchEnds

private java.util.Map<Label,java.util.List<TryCatchDetails>> tryCatchEnds
a map from try catch block end labels to the corresponding try catch block details -- the value is a list because the code reader will reuse the same label when two try catch blocks end at the same bytecode


tryCatchHandlers

private java.util.Map<Label,java.util.List<TryCatchDetails>> tryCatchHandlers
a map from try catch block handler labels to the corresponding try catch block details -- the value is a list because the code reader will reuse the same label when two handler blocks start at the same bytecode


currentTryCatchStarts

private java.util.List<TryCatchDetails> currentTryCatchStarts
a list of all try catch blocks which are started but not ended. this is updated as tryStart and tryEnd labels are visited.


openMonitorEnters

private java.util.Map<Label,java.util.List<CodeLocation>> openMonitorEnters
a map from block labels to any unclosed monitor enter instructions outstanding when the block is entered. this is only valid for blocks which are arrived at via conventional control flow i.e. not direct targets of try catch handler exceptions.


monitorPairs

private java.util.Map<CodeLocation,java.util.List<CodeLocation>> monitorPairs
a map from monitor enter instructions to the monitor exit insructions which close them. this is a list because an enter may have corresponding exits in exception handler blocks as well as the exit which is executed via normal control flow. Note that the latter is always the first entry in the list.


inverseMonitorPairs

private java.util.Map<CodeLocation,CodeLocation> inverseMonitorPairs
an inverse map from each monitor exit instruction to the monitor enter insructions it closes.


OVERLAPS

private static final int OVERLAPS
flag value passed to request a check for an overlap and returned to notify an overlap

See Also:
Constant Field Values

CONTAINS

private static final int CONTAINS
flag value passed to request a check for a containment and returned to notify a containment

See Also:
Constant Field Values

UNKNOWN

private static final int UNKNOWN
flag value returned to notify that a containment cannot yet be computed

See Also:
Constant Field Values
Constructor Detail

CFG

public CFG(java.lang.String methodName,
           Label start)
construct a CFG labelling the initial block with a given label

Parameters:
methodName - the name of the method fro which this is a CFG
start - a label for the entry block of the CFG
Method Detail

add

public void add(int instruction)
aopend an instruction to the current block

Parameters:
instruction -

add

public void add(int instruction,
                int operand)
append an instruction with one operand to the current block

Parameters:
instruction -
operand -

add

public void add(int instruction,
                int operand1,
                int operand2)
append an instruction with two operands to the current block

Parameters:
instruction -
operand1 -
operand2 -

add

public void add(int instruction,
                int[] operands)
append an operand with more than two operands ot the current block

Parameters:
instruction -
operands -

add

public void add(int instruction,
                java.lang.String name)
append an instruction with a String operand to the current block

Parameters:
instruction -
name -

add

public void add(int instruction,
                java.lang.String name,
                int dims)
append a multiarray create instruction to the current block

Parameters:
instruction -
name - the name of the array base type
dims - the number of array dimensions

add

public void add(int instruction,
                java.lang.String owner,
                java.lang.String name,
                java.lang.String desc)
append a field or method instruction with 3 String operands to the current block

Parameters:
instruction -
name -

setLocation

public CodeLocation setLocation(Label label)
set the location of a label to the next instruction offset in the current block

Parameters:
label - the label whose location is to be set

getLocation

public CodeLocation getLocation(Label label)
return the location of the label if known or null if it has not yet been reached. note that if this returns non-null then the label's offset in the generated bytecode can be safely retrieved but if it returns null then attempting to retrieve the offset will generate an exception.

Parameters:
label - the label whose location is desired
Returns:
the label's location if it has been reached otherwise null

hasLocation

public boolean hasLocation(Label label)
test whether the location of a label is known yet

Parameters:
label - the label whose location is desired
Returns:
true if the label's location has been reached otherwise false

nextLocation

public CodeLocation nextLocation()
return a location which will identify the next instruction added to the current block

Returns:
the location of the next instruction added to the current block

getBlock

public BBlock getBlock(Label label)
return the block containing a label if known

Parameters:
label - the label whose containing block is desired
Returns:
the label's location if it has been reached otherwise null

getContains

public FanOut getContains(BBlock block)
return a link object listing all the labels contained in a given block

Parameters:
block - the block whose labels are being sought
Returns:
the associated set of labels

addContains

private void addContains(BBlock block,
                         Label label)
add a label to the list of labels contained in a given block

Parameters:
block - the block whose containslist is to be updated
label - the label to be added to the list

getOpenMonitorEnters

public java.util.List<CodeLocation> getOpenMonitorEnters(Label label)
retrieve the list of monitor enter locations open at the start of a given block

Parameters:
label - the label of the block
Returns:
the list of open monitor enter locations

getOpenMonitors

public java.util.Iterator<CodeLocation> getOpenMonitors(TriggerDetails triggerDetails)
retrieve the list of monitor enter locations associated with a trigger block. this is called when we are inserting try catch handlers for trigger locations to determine whether they need to perform any monitor exit operations before executing the normal trigger exception handling code.

Parameters:
triggerDetails - the trigger being checked
Returns:
the list of locations for monitor enters open at the trigger start

addMonitorPair

void addMonitorPair(CodeLocation enter,
                    CodeLocation exit)
pair a monitor enter instruction with an associated monitor exit instructions

Parameters:
enter -
exit -

getPairedExit

private CodeLocation getPairedExit(CodeLocation enter,
                                   BBlock block)
locate a monitor exit instruction in block associated with a given monitor enter

Parameters:
enter -

getPairedEnter

public CodeLocation getPairedEnter(CodeLocation exit)
locate the monitor enter instruction associated with a given monitor exit

Parameters:
exit -

getSavedMonitorIdx

public int getSavedMonitorIdx(CodeLocation open)
return the index of the local var at which this monitorenter saved its lock object


carryForward

private void carryForward()
forward details of open monitor and try catch block locations from the current block to its reachable labels. This is always called just before splitting the current block.


computeContainment

private int computeContainment(CodeLocation tryStart,
                               CodeLocation tryEnd,
                               CodeLocation enter,
                               CodeLocation exit,
                               int flags)
compute whether the the region defined by a given enter and exit location pair overlaps or is contained within the region defined by a try start and end location pair when both regions ar erestricted to the current block

Parameters:
tryStart - the location of the start of the try region which will already have been visited
tryEnd - the location of the end of the try region which may be null because the end point has not been yet visited
enter - the location of the start of the monitor region which will already have been visited
exit - the location of an exit corresponding to the enter which may be null because the exit has not yet been visited
flags - OVERLAPS if an overlap is being checked for or CONTAINS if a containment is being checked for
Returns:
OVERLAPS if the monitor region overlaps the try region and an overlap is being checked for or CONTAINS if the monitor region is definitely contained within the try region and containment is being checked for or UNKNOWN if the monitor region cannot yet be determined to be contained within the try region and containment is being checked or 0 if there is no overlap and and an overlap is being checked for or 0 if there is definitely no containment and containment is being checked for.

tryStartMayContainEnter

private boolean tryStartMayContainEnter(CodeLocation tryStart,
                                        CodeLocation enter)
check whether the instructions exposed by a monitor enter may be contained within the scope of a tryStart. this is possible if the try start begins before the first instruction which follows the enter i.e. if the try start has a lower block idx than the enter or has the same block idx and an instruction offset less than or equal to the enter instruction idx + 1.

Parameters:
enter -
tryStart -
Returns:

split

public void split(Label newStart)
split the graph at a control-flow dead-end using the label provided to identify the new current block. the caller is obliged to call visitLabel immediately after calling this method to ensure that the current block label is indexed appropriately.

Parameters:
newStart - the label to be used to identify the new current block

split

public void split(Label newStart,
                  Label out)
split the graph at a control-flow goto point using the labels provided to identify the new current block and the goto target. the caller is obliged to call visitLabel immediately after calling this method to ensure that the current block label is indexed appropriately.

Parameters:
newStart - the label to be used to identify the new current block
out - the target of the GOTO

split

public void split(Label newStart,
                  Label out,
                  Label out2)
split the graph at a control-flow if branch point using the labels provided to identify the new current block the if branch target and the else branch target. the caller is obliged to call visitLabel immediately after calling this method to ensure that the current block label is indexed appropriately.

Parameters:
newStart - the label to be used to identify the new current block
out - the target of the if branch
out2 - the target of the else branch which probably ought to be the same label as passed for the current block (IF instructions assume drop-through)

split

public void split(Label newStart,
                  Label dflt,
                  Label[] labels)
split the graph at a control-flow switch branch point using the labels provided to identify the new current block, the switch case default branch target and the rest of the switch case branch targets. the caller is obliged to call visitLabel immediately after calling this method to ensure that the current block label is indexed appropriately.

Parameters:
newStart - the label to be used to identify the new current block
dflt - the switch case default branch target
labels - the other switch case branch targets

tryCatchStart

public boolean tryCatchStart(Label label)
test if a label marks the start of a try catch block

Parameters:
label - the label to be tested
Returns:
true if the label marks the start of a try catch block otherwise false

tryCatchEnd

public boolean tryCatchEnd(Label label)
test if a label marks the end of a try catch block

Parameters:
label - the label to be tested
Returns:
true if the label marks the start of a try catch block otherwise false

tryCatchHandlerStart

public boolean tryCatchHandlerStart(Label label)
test if a label marks the start of the handler for a try catch block

Parameters:
label - the label to be tested
Returns:
true if the label marks the start of a try catch block otherwise false

tryCatchStartDetails

public java.util.List<TryCatchDetails> tryCatchStartDetails(Label label)
return the list of details of try catch blocks which start at this label

Parameters:
label -
Returns:

tryCatchEndDetails

public java.util.List<TryCatchDetails> tryCatchEndDetails(Label label)
return the list of details of try catch blocks which end at this label

Parameters:
label -
Returns:

tryCatchHandlerStartDetails

public java.util.List<TryCatchDetails> tryCatchHandlerStartDetails(Label label)
return the list of details of try catch blocks whose handler startsend at this label

Parameters:
label -
Returns:

triggerStart

public boolean triggerStart(Label label)
test if a label marks the start of a trigger block

Parameters:
label - the label to be tested
Returns:
true if the label marks the start of a trigger block otherwise false

triggerEnd

public boolean triggerEnd(Label label)
test if a label marks the end of a trigger block

Parameters:
label - the label to be tested
Returns:
true if the label marks the start of a trigger block otherwise false

triggerStartDetails

public TriggerDetails triggerStartDetails(Label label)
return details of any trigger block which starts at this label

Parameters:
label -
Returns:

triggerEndDetails

public TriggerDetails triggerEndDetails(Label label)
return the list of details of try catch blocks which end at this label

Parameters:
label -
Returns:

triggerDetails

public java.util.Iterator<TriggerDetails> triggerDetails()
return an iterator ovver all known trigger detailsd

Returns:

visitLabel

public void visitLabel(Label label)
notify the CFG that a label has been visited by the method visitor and hence its position will now be resolved

Parameters:
label -

visitTriggerStart

public void visitTriggerStart(Label label)
notify the CFG that a label which represents the start of a trigger injection sequence has just been visited by the method visitor.

Parameters:
label -

visitTriggerEnd

public void visitTriggerEnd(Label label)
notify the CFG that a label which represents the end of a trigger injection sequence has just been visited by the method visitor.

Parameters:
label -

visitTryCatchBlock

public void visitTryCatchBlock(Label start,
                               Label end,
                               Label handler,
                               java.lang.String type)
notify the CFG of the location of a try catch block. note that this does not mean that the code generator has been notified of this information. these are normally notified to the method visitor before visiting the code. this is problematic if we want to insert our trigger point try catch blocks because we need to order them before any enclosing try catch blocks with wider scope. so the method visitor calls this routine up front but only notifies the try catch block to its super when the end label for the try catch block is reached.

Parameters:
start -
end -
handler -
type -

inBytemanHandler

public boolean inBytemanHandler()
check if the current block is a byteman-generated handler i.e. one which was created to catch an exception thrown by the byteman runtime. n.b. a byteman handler only ever spans one block.

Returns:
true if the current block is a byteman-generated handler

inRethrowHandler

public boolean inRethrowHandler()
return true if the current block is a rethrow handler i.e. one which was created to close a monitor exit instruction and then rethrow an exception. n.b. this must only be called when the next instruction to be added to the byetcode sequence is an ATHROW

Returns:
true if the current block is a rethrow handler

inBytemanTrigger

public boolean inBytemanTrigger()
check if the current block is a byteman-generated trigger section. this can be checked by testing whether there is an open try catch for one of the Byteman exception types

Returns:
true if the current block is a byteman-generated trigger section

visitMaxs

public void visitMaxs()
this can be called when the code generator call visiMaxs but it does nothing just now


visitEnd

public void visitEnd()

toString

public java.lang.String toString()
generate a string representation of the CFG

Overrides:
toString in class java.lang.Object
Returns:

getBlockInstructionIdx

public int getBlockInstructionIdx(Label label)
return the index of the label in its enclosing block's instruction sequence of -1 if the label has not yet been visited. the index can be used to lookup the insruction following the label.

Parameters:
label -
Returns:

getName

public java.lang.String getName(int nameIdx)