public final class BciBlockMapping extends Object
It also creates exception dispatch blocks for exception handling. These blocks are between a bytecode that might throw an exception, and the actual exception handler entries, and are later used to create the type checks with the exception handler catch types. If a bytecode is covered by an exception handler, this bytecode ends the basic block. This guarantees that a) control flow cannot be transferred to an exception dispatch block in the middle of a block, and b) that every block has at most one exception dispatch block (which is always the last entry in the successor list).
If a bytecode is covered by multiple exception handlers, a chain of exception dispatch blocks is created so that multiple exception handler types can be checked. The chains are re-used if multiple bytecodes are covered by the same exception handlers.
Note that exception unwinds, i.e., bytecodes that can throw an exception but the exception is not handled in this method, do not end a basic block. Not modeling the exception unwind block reduces the complexity of the CFG, and there is no algorithm yet where the exception unwind block would matter.
The class also handles subroutines (jsr and ret bytecodes): subroutines are inlined by duplicating the subroutine blocks. This is limited to simple, structured subroutines with a maximum subroutine nesting of 4. Otherwise, a bailout is thrown.
Loops in the methods are detected. If a method contains an irreducible loop (a loop with more than one entry), a bailout is thrown. This simplifies the compiler later on since only structured loops need to be supported.
A data flow analysis computes the live local variables from the point of view of the interpreter. The result is used later to prune frame states, i.e., remove local variable entries that are guaranteed to be never used again (even in the case of deoptimization).
The algorithms and analysis in this class are conservative and do not use any assumptions or profiling information.
Modifier and Type | Class and Description |
---|---|
static class |
BciBlockMapping.BciBlock |
static class |
BciBlockMapping.ExceptionDispatchBlock |
Modifier and Type | Field and Description |
---|---|
private BciBlockMapping.BciBlock[] |
blocks
The blocks found in this method, in reverse postorder.
|
private int |
blocksNotYetAssignedId |
private ExceptionHandler[] |
exceptionHandlers |
boolean |
hasJsrBytecodes |
private HashMap<ExceptionHandler,BciBlockMapping.ExceptionDispatchBlock> |
initialExceptionDispatch |
private ArrayList<BciBlockMapping.BciBlock> |
jsrVisited |
private static int |
LOOP_HEADER_INITIAL_CAPACITY |
private static int |
LOOP_HEADER_MAX_CAPACITY |
private boolean |
loopChanges |
private BciBlockMapping.BciBlock[] |
loopHeaders |
ResolvedJavaMethod |
method |
private int |
nextLoop
The next available loop number.
|
private int |
returnBci |
int |
returnCount |
private BciBlockMapping.BciBlock |
startBlock |
Modifier | Constructor and Description |
---|---|
private |
BciBlockMapping(ResolvedJavaMethod method)
Creates a new BlockMap instance from bytecode of the given method .
|
private BciBlockMapping.BciBlock[] blocks
public final ResolvedJavaMethod method
public boolean hasJsrBytecodes
private final ExceptionHandler[] exceptionHandlers
private BciBlockMapping.BciBlock startBlock
private BciBlockMapping.BciBlock[] loopHeaders
private static final int LOOP_HEADER_MAX_CAPACITY
private static final int LOOP_HEADER_INITIAL_CAPACITY
private int blocksNotYetAssignedId
public int returnCount
private int returnBci
private final ArrayList<BciBlockMapping.BciBlock> jsrVisited
private HashMap<ExceptionHandler,BciBlockMapping.ExceptionDispatchBlock> initialExceptionDispatch
private boolean loopChanges
private int nextLoop
private BciBlockMapping(ResolvedJavaMethod method)
method
- the compiler interface method containing the codepublic BciBlockMapping.BciBlock[] getBlocks()
public int getReturnCount()
public void build(BytecodeStream stream)
private boolean verify()
private void makeExceptionEntries(BciBlockMapping.BciBlock[] blockMap)
private void iterateOverBytecodes(BciBlockMapping.BciBlock[] blockMap, BytecodeStream stream)
private BciBlockMapping.BciBlock makeBlock(BciBlockMapping.BciBlock[] blockMap, int startBci)
private void addSwitchSuccessors(BciBlockMapping.BciBlock[] blockMap, int predBci, BytecodeSwitch bswitch)
private static void addSuccessor(BciBlockMapping.BciBlock[] blockMap, int predBci, BciBlockMapping.BciBlock sux)
private void createJsrAlternatives(BciBlockMapping.BciBlock[] blockMap, BciBlockMapping.BciBlock block)
private BciBlockMapping.ExceptionDispatchBlock handleExceptions(BciBlockMapping.BciBlock[] blockMap, int bci)
private void fixLoopBits(BciBlockMapping.BciBlock[] blockMap)
private void computeBlockOrder(BciBlockMapping.BciBlock[] blockMap)
private int handleLoopHeader(BciBlockMapping.BciBlock[] newBlocks, int nextStart, int i, BciBlockMapping.BciBlock loopHeader)
public void log(BciBlockMapping.BciBlock[] blockMap, String name)
public BciBlockMapping.BciBlock getLoopHeader(int index)
private void makeLoopHeader(BciBlockMapping.BciBlock block)
private long computeBlockOrder(BciBlockMapping.BciBlock block)
private long fixLoopBits(BciBlockMapping.BciBlock[] blockMap, BciBlockMapping.BciBlock block)
public static BciBlockMapping create(BytecodeStream stream, ResolvedJavaMethod method)
public BciBlockMapping.BciBlock[] getLoopHeaders()
public BciBlockMapping.BciBlock getStartBlock()
public BciBlockMapping.BciBlock getReturnBlock()
public BciBlockMapping.ExceptionDispatchBlock getUnwindBlock()
public int getLoopCount()
public int getBlockCount()