case class CFG[I <: AnyRef, C <: CodeSequence[I]](code: C, normalReturnNode: ExitNode, abnormalReturnNode: ExitNode, catchNodes: Seq[CatchNode], basicBlocks: Array[BasicBlock]) extends Product with Serializable
Represents the control flow graph of a method.
To compute a CFG
use the CFGFactory.
Thread-Safety
This class is thread-safe; all data is effectively immutable after construction time.
- code
The code for which the CFG was build.
- normalReturnNode
The unique exit node of the control flow graph if the method returns normally. If the method always throws an exception, this node will not have any predecessors.
- abnormalReturnNode
The unique exit node of the control flow graph if the method returns abnormally (throws an exception). If the method is guaranteed to never throw an exception, this node will not have any predecessors.
- catchNodes
List of all catch nodes. (Usually, we have one CatchNode per org.opalj.br.ExceptionHandler, but if an exception handler does not catch anything, no CatchNode is created.)
- basicBlocks
An implicit map between a program counter and its associated BasicBlock; it may be a sparse array!
- Alphabetic
- By Inheritance
- CFG
- Serializable
- Product
- Equals
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Instance Constructors
- new CFG(code: C, normalReturnNode: ExitNode, abnormalReturnNode: ExitNode, catchNodes: Seq[CatchNode], basicBlocks: Array[BasicBlock])
- code
The code for which the CFG was build.
- normalReturnNode
The unique exit node of the control flow graph if the method returns normally. If the method always throws an exception, this node will not have any predecessors.
- abnormalReturnNode
The unique exit node of the control flow graph if the method returns abnormally (throws an exception). If the method is guaranteed to never throw an exception, this node will not have any predecessors.
- catchNodes
List of all catch nodes. (Usually, we have one CatchNode per org.opalj.br.ExceptionHandler, but if an exception handler does not catch anything, no CatchNode is created.)
- basicBlocks
An implicit map between a program counter and its associated BasicBlock; it may be a sparse array!
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- val abnormalReturnNode: ExitNode
- def allBBs: Iterator[BasicBlock]
Iterates over the set of all BasicBlocks.
Iterates over the set of all BasicBlocks. (I.e., the exit and catch nodes are not returned.) Always returns the basic block containing the first instruction first.
- def allNodes: Iterator[CFGNode]
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- final def bb(pc: Int): BasicBlock
Returns the basic block to which the instruction with the given
pc
belongs.Returns the basic block to which the instruction with the given
pc
belongs.- pc
A valid pc.
- returns
The basic block associated with the given
pc
. If thepc
is not valid,null
is returned or an index out of bounds exception is thrown.
- val catchNodes: Seq[CatchNode]
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native() @IntrinsicCandidate()
- val code: C
- def dominatorTree: DominatorTree
- returns
Returns the dominator tree of this CFG.
- See also
DominatorTree.apply
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def foreachLogicalSuccessor(pc: Int)(f: (Int) => Unit): Unit
Iterates over the direct successors of the instruction with the given pc and calls the given function
f
for each successor.Iterates over the direct successors of the instruction with the given pc and calls the given function
f
for each successor.f
is guaranteed to be called only once for each successor instruction. (E.g., relevant in case of a switch where multiple cases are handled in the same way.) The value passed to f will either be:- the pc of an instruction.
- the value
CFG.AbnormalReturnId
(Int.MinValue
) in case the evaluation of the instruction with the given pc throws an exception that leads to an abnormal return. - the value
CFG.NormalReturnId
(Int.MaxValue
) in case the evaluation of the (return) instruction with the givenpc
leads to a normal return. -(successorPC)
if the evaluation leads to an exception that is caught and where the first instruction of the handler has the givensuccessorPC
.
- def foreachPredecessor(pc: Int)(f: (Int) => Unit): Unit
- def foreachSuccessor(pc: Int)(f: (PC) => Unit): Unit
Iterates over the direct successors of the instruction with the given pc and calls the given function
f
for each successor.Iterates over the direct successors of the instruction with the given pc and calls the given function
f
for each successor.f
is guaranteed to be called only once for each successor instruction. (E.g., relevant in case of a switch where multiple cases are handled in the same way.) - final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @IntrinsicCandidate()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- def mapPCsToIndexes[NewI <: AnyRef, NewC <: CodeSequence[NewI]](newCode: NewC, pcToIndex: Array[Int], singletonBBsExpander: (Int) => Int, lastIndex: Int): CFG[NewI, NewC]
Creates a new CFG where the boundaries of the basic blocks are updated given the
pcToIndex
mapping.Creates a new CFG where the boundaries of the basic blocks are updated given the
pcToIndex
mapping. The assumption is made that the indexes are continuous. If the first index (i.e.,pcToIndex(0)
is not 0, then a new basic block for the indexes in {0,pcToIndex(0)} is created if necessary.- singletonBBsExpander
Function called for each basic block which encompasses a single instruction to expand the BB to encompass more instructions. This supports the case where an instruction was transformed in a way that resulted in multiple instructions/statements, but which all belong to the same basic block. This situation cannot be handled using pcToIndex. This information is used to ensure that if a basic block, which currently just encompasses a single instruction, will encompass the new and the old instruction afterwards. The returned value will be used as the
endIndex.
endIndex = singletonBBsExpander(pcToIndex(pc of singleton bb))
Hence, the function is given the mapped index has to return that value if the index does not belong to the expanded instruction.- lastIndex
The index of the last instruction of the underlying (non-empty) code array. I.e., if the instruction array contains one instruction then the
lastIndex
has to be0
.
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- val normalReturnNode: ExitNode
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @IntrinsicCandidate()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @IntrinsicCandidate()
- final def performBackwardDataFlowAnalysis[Facts >: Null <: AnyRef](seed: Facts, t: (Facts, I, PC, PredecessorId) => Facts, join: (Facts, Facts) => Facts)(implicit arg0: ClassTag[Facts]): (Array[Facts], Facts)
Computes the maximum fixed point solution for backward data-flow analyses.
Computes the maximum fixed point solution for backward data-flow analyses.
- seed
The initial facts associated with instructions which lead to (ab)normal returns.
- t
The transfer function which implements the analysis:
(Facts, I, PC, CFG.PredecessorId) => Facts
. The parameters are: 1. the current set of facts, 2. the current instruction, 3. the program counter of the current instruction and 4. the id of the predecessor.- join
The operation (typically a set intersection or set union) that is executed to join the results of the successors of a specific instruction. It is required that join returns the left (first) set as is if the set of facts didn't change. I.e., even if the left and right sets contain the same values and are
equal
(==
) it is necessary to return the left set.
- Note
No facts will derived for stmts that are not reachable from an exit node; e.g., due to an infinite loop. That is, the returned array may contain
null
values and in an extreme case will only contain null values!
- final def performForwardDataFlowAnalysis[Facts >: Null <: AnyRef](seed: Facts, t: (Facts, I, PC, SuccessorId) => Facts, join: (Facts, Facts) => Facts)(implicit arg0: ClassTag[Facts]): (Array[Facts], Facts, Facts)
Computes the maximum fixed point solution for forward data-flow analyses.
Computes the maximum fixed point solution for forward data-flow analyses.
- seed
The initial facts associated with the first instruction (pc = 0).
- t
The transfer function which implements the analysis:
(Facts, I, PC, CFG.SuccessorId) => Facts
. The parameters are: 1. the current set of facts, 2. the current instruction, 3. the program counter of the current instruction and 4. the id of the successor.- join
The operation (typically a set intersection or set union) that is executed to join the results of the predecessors of a specific instruction. It is required that join returns the left (first) set as is if the set of facts didn't change. I.e., even if the left and right sets contain the same values and are
equal
(==
) it is necessary to return the left set.
- def predecessors(pc: Int): IntTrieSet
- def productElementNames: Iterator[String]
- Definition Classes
- Product
- lazy val reachableBBs: Set[CFGNode]
Returns the set of all reachable CFGNodes of the control flow graph.
- final def startBlock: BasicBlock
The basic block associated with the very first instruction.
- def successors(pc: Int): IntTrieSet
Returns all direct runtime successors of the instruction with the given pc.
Returns all direct runtime successors of the instruction with the given pc.
If the returned set is empty, then the instruction is either a return instruction or an instruction that always causes an exception to be thrown that is not handled by a handler of the respective method.
- pc
A valid pc of an instruction of the code block from which this cfg was derived.
- Note
If possible, the function
foreachSuccessor
should be used as it does not have to create comparatively expensive intermediate data structures.
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toDot(f: (BasicBlock) => String, includeAbnormalReturns: Boolean = true): (Node, Iterable[Node])
- returns
The pair:
(Node for the start BB, all Nodes (incl. the node for the start BB))
- def toDot: String
- def toString(): String
- Definition Classes
- CFG → AnyRef → Any
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
Deprecated Value Members
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable]) @Deprecated
- Deprecated