Package kilim.analysis
Class BasicBlock
java.lang.Object
kilim.analysis.BasicBlock
- All Implemented Interfaces:
Comparable<BasicBlock>
A basic block is a contiguous set of instructions that has one label at the
first instruction and a transfer-of-control instruction at the very end. A
transfer-of-control instruction includes all branching instructions that have
labelled targets (IF_x, GOTO, and JSR) and the rest (ATHROW, xRETURN, RET).
There can be no target labels in the middle of a basic block; in other words,
you can't jump into the middle of a basic block. This is the standard
definition; we make a few changes.
We create BasicBlocks whenever we encounter a label (in a linear
scanning of a method's instructions. Some labels are meant for catch
handlers and debug (line number) information only; they are not the
target of a branching instruction, but we don't know that in the
first pass. We coalesce those BasicBlocks that merely follow
another, provided the preceding BB is the only preceder. Note that
blocks connected with a GOTO can't coalesce because they are not
likely to be contiguous, even if they obey the constraint of a
single edge. We also don't coalesce blocks starting with a pausable method
invocation with their predecessor, because we need these blocks to
tell us about downstream usage of local vars to help us generate
optimal continuations.
All catch handlers that intersect a basic block are treated as
successors to the block, for the purposes of liveness analysis.
Subroutines (targets of JSR) are treated specially. We inline all JSR
calls, including nested JSRs, to simplify liveness analysis. In this phase, a
JSR/RET is treated the same as a GOTO sub followed by a GOTO to the caller.
During the weaving phase, we ignore the inlining information if the
subroutine doesn't have any pausable methods. If it does, then we spit out
duplicate code, complete with GOTOs as described above. This allows us to
jump in the middle of a "finally" block during rewinding.
Note: The JVM reference doesn't specify the boundaries of a JSR instruction;
in other words, there is no definitive way of saying which blocks belong to a
subroutine. This code treats the set of all nodes reachable via branching
instructions from the subroutine's entry point. (exception catch blocks don't
count)
-
Field Summary
FieldsModifier and TypeFieldDescription(package private) String(package private) static final intint(package private) static final int(package private) intThe flow to which this BB belongs.(package private) BasicBlockintA number handed out in increasing order of starting position, to ease sorting as well as for debug information(package private) static final int(package private) static final int(package private) int(package private) static final int(package private) static final intThe frame at the BB's entry point.org.objectweb.asm.tree.LabelNodeThe label that starts this BB.intStart and end points (both inclusive) in the current method's list of instructions (this.flow.instructions)(package private) static final int(package private) ArrayList<BasicBlock> (package private) static final intList of successors (follower and all branch targets).A cached version of all sucessors' usage, successors being catch handlers and real successors.usage initially contains the usage of local variables in this block (without reference to any other block).(package private) booleanthe block has already been visited during the born calculation -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) void(package private) void(package private) void(package private) voidchangeLastInsnToGOTO(org.objectweb.asm.tree.LabelNode label) (package private) voidvoidchooseCatchHandlers(ArrayList<Handler> handlerList) (package private) voidint(package private) voiddupBBAndLabels(boolean deepCopy, HashMap<BasicBlock, BasicBlock> bbCopyMap, HashMap<org.objectweb.asm.tree.LabelNode, org.objectweb.asm.tree.LabelNode> labelCopyMap, BasicBlock returnToBB) (package private) static ArrayList<BasicBlock> dupCopyContents(boolean deepCopy, BasicBlock targetBB, BasicBlock returnToBB, HashMap<BasicBlock, BasicBlock> bbCopyMap, HashMap<org.objectweb.asm.tree.LabelNode, org.objectweb.asm.tree.LabelNode> labelCopyMap) booleancalculate the liveness usage by evolution (assume born usage has already been calculated)(package private) BasicBlockorg.objectweb.asm.tree.AbstractInsnNodegetInstruction(int pos) booleanhasFlag(int bitFlag) (package private) intinitialize(int pos) Absorb as many instructions until the next label or the next transfer of control instruction.(package private) ArrayList<BasicBlock> inline()This basic block's last instruction is JSR.(package private) voidbooleanboolean(package private) booleanboolean(package private) int(package private) void(package private) voidmergeSuccessors(Frame frame) (package private) Stringpretty print successor and catch BB idsvoidsetFlag(int bitFlag) (package private) voidsetId(int aid) (package private) voidsetInstruction(int pos, org.objectweb.asm.tree.AbstractInsnNode insn) toString()voidunsetFlag(int bitFlag)
-
Field Details
-
id
public int idA number handed out in increasing order of starting position, to ease sorting as well as for debug information -
flags
int flags -
ENQUEUED
static final int ENQUEUED- See Also:
-
SUBROUTINE_CLAIMED
static final int SUBROUTINE_CLAIMED- See Also:
-
COALESCED
static final int COALESCED- See Also:
-
PAUSABLE
static final int PAUSABLE- See Also:
-
IS_SUBROUTINE
static final int IS_SUBROUTINE- See Also:
-
SUB_BLOCK
static final int SUB_BLOCK- See Also:
-
INLINE_CHECKED
static final int INLINE_CHECKED- See Also:
-
PAUSABLE_SUB
static final int PAUSABLE_SUB- See Also:
-
flow
The flow to which this BB belongs. -
startLabel
public org.objectweb.asm.tree.LabelNode startLabelThe label that starts this BB. In some cases we create a label where it didn't exist originally (after a jmp instruction, for example). This allows us a unique indexing scheme. -
startPos
public int startPosStart and end points (both inclusive) in the current method's list of instructions (this.flow.instructions) -
endPos
public int endPos -
successors
List of successors (follower and all branch targets). Should be null -
handlers
-
numPredecessors
int numPredecessors -
usage
usage initially contains the usage of local variables in this block (without reference to any other block). After flow analysis it contains the combined effect of this and all downstream blocks -
visited
boolean visitedthe block has already been visited during the born calculation -
succUsage
A cached version of all sucessors' usage, successors being catch handlers and real successors. -
handUsage
-
startFrame
The frame at the BB's entry point. It changes when propagating changes from its predeccessors, until there's a fixed point. -
caughtExceptionType
String caughtExceptionType -
follower
BasicBlock follower -
subBlocks
ArrayList<BasicBlock> subBlocks
-
-
Constructor Details
-
BasicBlock
-
-
Method Details
-
initialize
int initialize(int pos) Absorb as many instructions until the next label or the next transfer of control instruction. In the first pass we may end up creating many many BBs because there may be a lot of non-target labels (esp. when debug information is available). The constraints are as follows: 1. A transfer of control instruction must be the last instruction. It may also be the first (and only) instruction 2. A labeled instruction must be the first instruction in a BB. It may optionally be the last (and only) instruction 3. A pausable method is treated like a labeled instruction, and is given a label if there isn't one already. Constraint 2 applies. -
addFollower
-
addSuccessor
-
getVarUsage
-
lastInstruction
int lastInstruction() -
coalesceTrivialFollowers
void coalesceTrivialFollowers() -
setFlag
public void setFlag(int bitFlag) -
unsetFlag
public void unsetFlag(int bitFlag) -
hasFlag
public boolean hasFlag(int bitFlag) -
compareTo
- Specified by:
compareToin interfaceComparable<BasicBlock>
-
interpret
void interpret() -
isCatchHandler
public boolean isCatchHandler() -
mergeSuccessors
-
merge
- Parameters:
inframe-localsOnly-
-
chooseCatchHandlers
-
getInstruction
public org.objectweb.asm.tree.AbstractInsnNode getInstruction(int pos) -
printGeniology
String printGeniology()pretty print successor and catch BB ids -
flowVarUsage
public boolean flowVarUsage()calculate the liveness usage by evolution (assume born usage has already been calculated) -
inline
This basic block's last instruction is JSR. This method initiates a subgraph traversal to identify the called subroutine's boundaries and to make all encountered RET instructions point back to this BB's follower, in essence turning it to a goto. The reason for not actually turning it into a GOTO is that if we don't find any pausable methods in a subroutine, then during code generation we'll simply use the original code. The duplication is still required for flow analysis. The VM spec is fuzzy on what constitutes the boundaries of a subroutine. We consider the following situations invalid, even though the verifier is ok with it: (a) looping back to itself (b) encountering xRETURN in a subroutine inline() traverses the graph creating copies of BasicBlocks and labels and keeps a mapping between the old and the new. In the second round, it copies instructions translating any that have labels (branch and switch instructions).- Returns:
- mapping of orig basic blocks to new.
- Throws:
KilimException
-
dupBBAndLabels
void dupBBAndLabels(boolean deepCopy, HashMap<BasicBlock, BasicBlock> bbCopyMap, HashMap<org.objectweb.asm.tree.LabelNode, throws KilimExceptionorg.objectweb.asm.tree.LabelNode> labelCopyMap, BasicBlock returnToBB) - Throws:
KilimException
-
dupCopyContents
static ArrayList<BasicBlock> dupCopyContents(boolean deepCopy, BasicBlock targetBB, BasicBlock returnToBB, HashMap<BasicBlock, BasicBlock> bbCopyMap, HashMap<org.objectweb.asm.tree.LabelNode, throws KilimExceptionorg.objectweb.asm.tree.LabelNode> labelCopyMap) - Throws:
KilimException
-
getJSRTarget
-
getSubBlocks
- Throws:
KilimException
-
getFollowingBlock
BasicBlock getFollowingBlock() -
toString
-
isPausable
public boolean isPausable() -
setId
void setId(int aid) -
checkPausableJSR
- Throws:
KilimException
-
changeJSR_RET_toGOTOs
- Throws:
KilimException
-
setInstruction
void setInstruction(int pos, org.objectweb.asm.tree.AbstractInsnNode insn) -
changeLastInsnToGOTO
void changeLastInsnToGOTO(org.objectweb.asm.tree.LabelNode label) -
isGetCurrentTask
public boolean isGetCurrentTask() -
isInitialized
boolean isInitialized()
-