public class BciBlockMapping extends Object implements JavaMethodContext
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.
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 or, if BciBlockMapping.Options.MaxDuplicationFactor > 1,
block duplication is attempted to make the loop reducible. 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 |
static class |
BciBlockMapping.Options |
| Modifier and Type | Field and Description |
|---|---|
protected BitSet[] |
bciExceptionHandlerIDs |
protected BciBlockMapping.BciBlock[] |
blockMap |
protected int |
blocksNotYetAssignedId |
Bytecode |
code |
protected ExceptionHandler[] |
exceptionHandlers |
boolean |
hasJsrBytecodes |
protected static int |
UNASSIGNED_ID |
| Modifier | Constructor and Description |
|---|---|
protected |
BciBlockMapping(Bytecode code,
DebugContext debug)
Creates a new BlockMap instance from
code. |
protected |
BciBlockMapping(Bytecode code,
DebugContext debug,
int maxDuplicationBoost)
Creates a new BlockMap instance from
code. |
| Modifier and Type | Method and Description |
|---|---|
protected void |
addInvokeNormalSuccessor(int invokeBci,
BciBlockMapping.BciBlock sux)
Logic for adding an the "normal" invoke successor link.
|
JavaMethod |
asJavaMethod() |
boolean |
bciUnique() |
void |
build(BytecodeStream stream,
OptionValues options,
boolean splitExceptionRanges)
Builds the block map and conservative CFG and numbers blocks.
|
protected static void |
buildMap(BytecodeStream stream,
Bytecode code,
OptionValues options,
DebugContext debug,
BciBlockMapping map,
boolean splitExceptionRanges) |
void |
clearLivenessMetadata()
After local liveness has been computed, some metadata no longer needs to be retained.
|
static BciBlockMapping |
create(BytecodeStream stream,
Bytecode code,
OptionValues options,
DebugContext debug,
boolean hasAsyncExceptions) |
static BciBlockMapping |
create(BytecodeStream stream,
Bytecode code,
OptionValues options,
DebugContext debug,
boolean hasAsyncExceptions,
int maxDuplicationBoost) |
BitSet |
getBciExceptionHandlerIDs(int bci) |
int |
getBlockCount() |
BciBlockMapping.BciBlock[] |
getBlocks() |
BciBlockMapping.BciBlock |
getHandlerBlock(int handlerID) |
protected BciBlockMapping.BciBlock |
getInstructionBlock(int bci)
Retrieve the instruction block corresponding to this bci.
|
int |
getLoopCount() |
BciBlockMapping.BciBlock |
getLoopHeader(int index)
Get the header block for a loop index.
|
BciBlockMapping.BciBlock[] |
getLoopHeaders() |
BciBlockMapping.BciBlock |
getStartBlock() |
BciBlockMapping.ExceptionDispatchBlock |
getUnwindBlock() |
protected BciBlockMapping.ExceptionDispatchBlock |
handleExceptions(int bci,
boolean processNewBlock,
boolean isInvoke) |
protected boolean |
isStartOfNewBlock(BciBlockMapping.BciBlock current,
int bci)
Check whether this bci should be the start of a new block.
|
void |
log(BciBlockMapping.BciBlock[] blockArray,
String name) |
protected Set<BciBlockMapping.BciBlock> |
makeExceptionEntries(boolean splitRanges)
Makes exception entries and splits blocks at exception handlers if requested.
|
protected BciBlockMapping.BciBlock |
processNewBciBlock(int bci,
BciBlockMapping.BciBlock newBlock)
A hook for subclasses to insert additional blocks around a newly created BciBlock.
|
protected BciBlockMapping.ExceptionDispatchBlock |
processNewExceptionDispatchBlock(int bci,
boolean isInvoke,
BciBlockMapping.ExceptionDispatchBlock handler)
A hook for subclasses to insert additional blocks around a newly created
ExceptionDispatchBlock.
|
protected BciBlockMapping.BciBlock |
startNewBlock(int bci)
Wrapper around makeBlock.
|
String |
toString() |
static String |
toString(BciBlockMapping.BciBlock[] blockMap,
BciBlockMapping.BciBlock[] loopHeadersMap) |
protected boolean |
verify() |
protected static final int UNASSIGNED_ID
protected BciBlockMapping.BciBlock[] blockMap
public final Bytecode code
public boolean hasJsrBytecodes
protected final ExceptionHandler[] exceptionHandlers
protected BitSet[] bciExceptionHandlerIDs
protected int blocksNotYetAssignedId
protected BciBlockMapping(Bytecode code, DebugContext debug)
code.protected BciBlockMapping(Bytecode code, DebugContext debug, int maxDuplicationBoost)
code.maxDuplicationBoost - amount by which to multiply BciBlockMapping.Options.MaxDuplicationFactorpublic BciBlockMapping.BciBlock[] getBlocks()
public BitSet getBciExceptionHandlerIDs(int bci)
public BciBlockMapping.BciBlock getHandlerBlock(int handlerID)
public boolean bciUnique()
public void clearLivenessMetadata()
public void build(BytecodeStream stream, OptionValues options, boolean splitExceptionRanges)
protected boolean verify()
protected BciBlockMapping.BciBlock startNewBlock(int bci)
protected Set<BciBlockMapping.BciBlock> makeExceptionEntries(boolean splitRanges)
protected boolean isStartOfNewBlock(BciBlockMapping.BciBlock current, int bci)
protected BciBlockMapping.BciBlock getInstructionBlock(int bci)
protected BciBlockMapping.BciBlock processNewBciBlock(int bci, BciBlockMapping.BciBlock newBlock)
protected void addInvokeNormalSuccessor(int invokeBci,
BciBlockMapping.BciBlock sux)
protected BciBlockMapping.ExceptionDispatchBlock processNewExceptionDispatchBlock(int bci, boolean isInvoke, BciBlockMapping.ExceptionDispatchBlock handler)
protected BciBlockMapping.ExceptionDispatchBlock handleExceptions(int bci, boolean processNewBlock, boolean isInvoke)
public void log(BciBlockMapping.BciBlock[] blockArray, String name)
public static String toString(BciBlockMapping.BciBlock[] blockMap, BciBlockMapping.BciBlock[] loopHeadersMap)
public BciBlockMapping.BciBlock getLoopHeader(int index)
public static BciBlockMapping create(BytecodeStream stream, Bytecode code, OptionValues options, DebugContext debug, boolean hasAsyncExceptions)
public static BciBlockMapping create(BytecodeStream stream, Bytecode code, OptionValues options, DebugContext debug, boolean hasAsyncExceptions, int maxDuplicationBoost)
protected static void buildMap(BytecodeStream stream, Bytecode code, OptionValues options, DebugContext debug, BciBlockMapping map, boolean splitExceptionRanges)
public BciBlockMapping.BciBlock[] getLoopHeaders()
public BciBlockMapping.BciBlock getStartBlock()
public BciBlockMapping.ExceptionDispatchBlock getUnwindBlock()
public int getLoopCount()
public int getBlockCount()
public JavaMethod asJavaMethod()
asJavaMethod in interface JavaMethodContext