|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.jikesrvm.compilers.opt.bc2ir.BC2IR
public final class BC2IR
This class translates from bytecode to HIR.
The only public entry point is BC2IR.generateHIR. generateHIR is passed an argument GenerationContext. The context is assumed to be "empty" but "initialized." Invoking generateHIR on a context results in it being "filled in" with the HIR for the method (and for any inlined methods) as specified by the state of the context.
The basic idea is to abstractly interpret the bytecode stream, translating it into a register-based IR along the way. At each program point BC2IR has an abstract stack and an abstract local variable array. Based on this, and on the bytecode, it can generate instructions. It also does a number of forward flow-sensitive dataflow analyses and optimistic optimizations in the process. There's lots of details in John Whaley's master thesis from MIT. However, one needs to be careful because this code has substantial diverged from the system described in his thesis. Some optimizations/features described in Johns's thesis are not implemented here. Some optimizations/features implemented here are not described in John's thesis. In particular this code takes a different approach to JSRs (inlining them), and has more advanced and effective implementation of the inlining transformation.
IRGenOptions
,
GenerationContext
,
ConvertBCtoHIR
Nested Class Summary | |
---|---|
private static class |
BC2IR.DummyStackSlot
Dummy stack slot |
Field Summary | |
---|---|
private Operand[] |
_localState
Current state of local variables. |
private int |
bciAdjustment
OSR field: TODO rework this mechanism! |
private BytecodeStream |
bcodes
Bytecodes for the method being generated. |
private BBSet |
blocks
The set of BasicBlockLEs we are generating |
private BasicBlockLE |
currentBBLE
Current BBLE. |
private Operand |
currentGuard
|
(package private) static boolean |
DBG_SELECTED
|
private static boolean |
DBG_SELECTIVE
Debugging with method_to_print. |
static BC2IR.DummyStackSlot |
DUMMY
Dummy slot. |
private boolean |
endOfBasicBlock
Does basic block end here? |
private boolean |
fallThrough
Do we fall through to the next basic block? |
private GenerationContext |
gc
The generation context. |
private boolean |
inlinedSomething
Was something inlined? |
private int |
instrIndex
Bytecode index of current instruction. |
private Instruction |
lastInstr
Last instruction generated (for ELIM_COPY_LOCALS) |
private Instruction |
lastOsrBarrier
osr barrier needs type information of locals and stacks, it has to be created before a _callHelper. |
private boolean |
osrGuardedInline
|
private int |
param1
OSR: used for PSEUDO_InvokeStatic to recover the type info |
private int |
param2
OSR: used for PSEUDO_InvokeStatic to recover the type info |
private int |
runoff
Index of next basic block. |
private OperandStack |
stack
Current simulated stack state. |
Fields inherited from interface org.jikesrvm.compilers.opt.bc2ir.IRGenOptions |
---|
CF_CHECKCAST, CF_CHECKSTORE, CF_DOUBLECMP, CF_FLOATCMP, CF_INSTANCEOF, CF_INTIF, CF_INTIFCMP, CF_LONGCMP, CF_LOOKUPSWITCH, CF_REFIF, CF_REFIFCMP, CF_TABLESWITCH, CP_IN_LOCALS, DBG_ALL, DBG_BB, DBG_BBSET, DBG_BCPARSE, DBG_CF, DBG_CFG, DBG_ELIMCOPY, DBG_ELIMNULL, DBG_EX, DBG_FLATTEN, DBG_INLINE_JSR, DBG_INSTR, DBG_LOCAL, DBG_OPERAND_LATTICE, DBG_REGEN, DBG_STACK, DBG_TYPE, ELIM_COPY_LOCALS, LOCALS_ON_STACK, MAX_RETURN_ADDRESSES |
Fields inherited from interface org.jikesrvm.compilers.opt.driver.OptConstants |
---|
EPILOGUE_BCI, EPILOGUE_BLOCK_BCI, EXTANT_ANALYSIS_BCI, INSTRUMENTATION_BCI, MAYBE, METHOD_COUNTER_BCI, NO, OSR_PROLOGUE, PROLOGUE_BCI, PROLOGUE_BLOCK_BCI, RECTIFY_BCI, RUNTIME_SERVICES_BCI, SSA_SYNTH_BCI, SYNCHRONIZED_MONITORENTER_BCI, SYNCHRONIZED_MONITOREXIT_BCI, SYNTH_CATCH_BCI, SYNTH_LOOP_VERSIONING_BCI, UNKNOWN_BCI, YES |
Fields inherited from interface org.jikesrvm.osr.OSRConstants |
---|
ACONST, BCI_MASK, BCI_SHIFT, CLEANREFS, DOUBLE, FLOAT, GETREFAT, HIGH_64BIT, ICONST, IEI_MASK, IEI_SHIFT, INT, INVALID_BCI, INVALID_IEI, KIND_MASK, KIND_SHIFT, LCONST, LOCAL, LONG, NEXT_BIT, NO_OSR_ENTRY, NUM_MASK, NUM_SHIFT, OFFSET_MASK, OFFSET_SHIFT, OSRI_MASK, OSRI_SHIFT, PHYREG, PSEUDO_CheckCast, PSEUDO_InvokeCompiledMethod, PSEUDO_InvokeStatic, PSEUDO_LoadDoubleConst, PSEUDO_LoadFloatConst, PSEUDO_LoadIntConst, PSEUDO_LoadLongConst, PSEUDO_LoadRetAddrConst, PSEUDO_LoadWordConst, PSEUDO_ParamInitEnd, REF, RET_ADDR, ReturnAddressTypeCode, SPILL, STACK, TCODE_MASK, TCODE_SHIFT, VTYPE_MASK, VTYPE_SHIFT, WORD, WordTypeCode |
Constructor Summary | |
---|---|
private |
BC2IR()
|
private |
BC2IR(GenerationContext context)
Construct the BC2IR object for the generation context. |
Method Summary | |
---|---|
Instruction |
_aloadHelper(Operator operator,
Operand ref,
Operand index,
TypeReference type)
|
private Instruction |
_binaryDualHelper(Operator operator,
Operand op1,
Operand op2,
TypeReference type)
|
private Instruction |
_binaryHelper(Operator operator,
Operand op1,
Operand op2,
TypeReference type)
|
private Instruction |
_callHelper(MethodReference meth,
MethodOperand methOp)
Pop method parameters off the expression stack. |
private Instruction |
_createOsrBarrier()
|
private Instruction |
_gotoHelper(int offset)
|
private Instruction |
_guardedBinaryDualHelper(Operator operator,
Operand op1,
Operand op2,
Operand guard,
TypeReference type)
|
private Instruction |
_guardedBinaryHelper(Operator operator,
Operand op1,
Operand op2,
Operand guard,
TypeReference type)
|
private Instruction |
_intIfCmpHelper(ConditionOperand cond)
|
private Instruction |
_intIfHelper(ConditionOperand cond)
|
private Instruction |
_jsrHelper(int offset)
|
private Operand |
_loadLocalForOSR(Operand op)
make a temporary register, and create a move instruction |
private Instruction |
_moveDualHelper(Operator operator,
Operand val,
TypeReference type)
|
private Instruction |
_moveHelper(Operator operator,
Operand val,
TypeReference type)
|
static Instruction |
_osrHelper(Instruction barrier)
Creates an OSR point instruction with its dependent OsrBarrier which provides type and variable information. |
private Operand |
_prepareDoubleConstant(Operand op)
special process for long/double constants |
private Operand |
_prepareLongConstant(Operand op)
special process for long/double constants |
private Instruction |
_refIfCmpHelper(ConditionOperand cond)
|
private Instruction |
_refIfNullHelper(ConditionOperand cond)
|
private Instruction |
_retHelper(int var)
|
private void |
_returnHelper(Operator operator,
Operand val)
|
private Instruction |
_unaryDualHelper(Operator operator,
Operand val,
TypeReference type)
|
private Instruction |
_unaryHelper(Operator operator,
Operand val,
TypeReference type)
|
void |
appendInstruction(Instruction s)
Append an instruction to the current basic block. |
private void |
assertIsAssignable(TypeReference parentType,
TypeReference childType)
Assert that the given child type is a subclass of the given parent type. |
void |
assertIsType(Operand op,
TypeReference type)
Assert that the given operand is of the given type, or of a subclass of the given type. |
void |
clearCurrentGuard()
|
private boolean |
couldCauseClassLoading(TypeReference typeRef)
|
private void |
db(String val)
Print a debug string to the sysWrite stream |
private Instruction |
do_aload(int index)
Simulate a load from a given local variable of a reference. |
private Instruction |
do_astore(int index)
Simulate a store into a given local variable of an object ref. |
boolean |
do_BoundsCheck(Operand ref,
Operand index)
Generate a boundscheck instruction for the given operand and index. |
private boolean |
do_CheckStore(Operand ref,
Operand elem,
TypeReference elemType)
Generate a storecheck for the given array and elem |
private Instruction |
do_dload(int index)
Simulate a load from a given local variable of a double. |
private Instruction |
do_fload(int index)
Simulate a load from a given local variable of a float. |
private Instruction |
do_iinc(int index,
int amount)
Simulate the incrementing of a given int local variable. |
private Instruction |
do_iload(int index)
Simulate a load from a given local variable of an int. |
private boolean |
do_IntZeroCheck(Operand div)
Generate a check for 0 for the given operand |
private Instruction |
do_lload(int index)
Simulate a load from a given local variable of a long. |
private boolean |
do_LongZeroCheck(Operand div)
Generate a check for 0 for the given operand |
boolean |
do_NullCheck(Operand ref)
Generate a null-check instruction for the given operand. |
private Instruction |
do_store(int index,
Operand op1)
Simulate a store into a given local variable of an int/long/double/float Returns generated instruction (or null if no instruction generated.) |
private void |
finish(GenerationContext context)
|
Instruction |
generateAnewarray(TypeReference arrayTypeRef,
TypeReference elementTypeRef)
|
private void |
generateFrom(int fromIndex)
Generate instructions for a basic block. |
private void |
generateHIR()
Main generation loop. |
static void |
generateHIR(GenerationContext context)
Generate HIR as specified by the argument GenerationContext. |
private BranchOperand |
generateTarget(int offset)
|
TypeReference |
getArrayTypeOf(Operand op)
Return the data type of the given operand, assuming that the operand is an array reference. |
Operand |
getConstantOperand(int index)
Fetch the value of the next operand, a constant, from the bytecode stream. |
Operand |
getCurrentGuard()
|
static Operand |
getGuard(Operand op)
|
private Operand |
getLocal(int i)
Gets the specified local variable. |
private Operand |
getLocalDual(int i)
Gets the specified local variable (long, double). |
private BasicBlockLE |
getOrCreateBlock(int target)
Get or create a block at the specified target. |
private BasicBlockLE |
getOrCreateBlock(int target,
BasicBlockLE from,
OperandStack simStack,
Operand[] simLocals)
Get or create a block at the specified target. |
private TypeReference |
getRefTypeOf(Operand op)
Return the data type of the given operand, assuming that the operand is a reference. |
static boolean |
hasGuard(RegisterOperand rop)
|
static boolean |
hasLessConservativeGuard(RegisterOperand rop1,
RegisterOperand rop2)
|
static boolean |
isNonNull(Operand op)
|
private LocationOperand |
makeInstanceFieldRef(FieldReference f)
|
private LocationOperand |
makeStaticFieldRef(FieldReference f)
Make a field reference operand referring to the given field with the given type. |
private TypeOperand |
makeTypeOperand(RVMType type)
Make a type operand that refers to the given type. |
private TypeOperand |
makeTypeOperand(TypeReference type)
Make a type operand that refers to the given type. |
(package private) void |
markBBUnsafeForScheduling()
HACK: Mark current basic block unsafe for scheduling. |
void |
markGuardlessNonNull(RegisterOperand rop)
|
private boolean |
maybeInlineMethod(InlineDecision inlDec,
Instruction callSite)
Attempt to inline a method. |
(package private) Operand |
pop()
Pop an operand from the stack. |
(package private) Operand |
pop(TypeReference type)
Pop an operand of the given type from the stack. |
Operand |
popAddress()
Pop a ref operand from the stack. |
(package private) Operand |
popDouble()
Pop a double operand from the stack. |
(package private) void |
popDummy()
Pop a dummy operand from the stack. |
(package private) Operand |
popFloat()
Pop a float operand from the stack. |
Operand |
popInt()
Pop an int operand from the stack. |
(package private) Operand |
popLong()
Pop a long operand from the stack. |
Operand |
popRef()
Pop a ref operand from the stack. |
private Operand |
popShiftInt(boolean longShift)
Pop an int from the stack to be used in a shift. |
private String |
printBlocks()
Return a string representation of the current basic block set. |
void |
push(Operand r)
Push a single width operand (int, float, ref, ...) on the simulated stack. |
(package private) void |
push(Operand r,
TypeReference type)
Push an operand of the specified type on the simulated stack. |
private Instruction |
pushCopy(Operand op1)
Push a copy of the given operand onto simulated stack. |
private Instruction |
pushCopy(Operand op1,
int b1)
Push a copy of the given operand onto simulated stack. |
(package private) void |
pushDual(Operand r)
Push a double width operand (long, double) on the simulated stack. |
private BasicBlock |
rectifyStateWithArithmeticExceptionHandler()
|
private BasicBlock |
rectifyStateWithArithmeticExceptionHandler(boolean linkToExitIfUncaught)
|
private BasicBlock |
rectifyStateWithArrayBoundsExceptionHandler()
|
private BasicBlock |
rectifyStateWithArrayBoundsExceptionHandler(boolean linkToExitIfUncaught)
|
private BasicBlock |
rectifyStateWithArrayStoreExceptionHandler()
|
private BasicBlock |
rectifyStateWithArrayStoreExceptionHandler(boolean linkToExitIfUncaught)
|
private BasicBlock |
rectifyStateWithErrorHandler()
|
private BasicBlock |
rectifyStateWithErrorHandler(boolean linkToExitIfUncaught)
|
BasicBlock |
rectifyStateWithExceptionHandler(TypeReference exceptionType)
|
private BasicBlock |
rectifyStateWithExceptionHandler(TypeReference exceptionType,
boolean linkToExitIfUncaught)
|
void |
rectifyStateWithExceptionHandlers()
|
private void |
rectifyStateWithExceptionHandlers(boolean linkToExitIfUncaught)
|
private BasicBlock |
rectifyStateWithNullPtrExceptionHandler()
|
private BasicBlock |
rectifyStateWithNullPtrExceptionHandler(boolean linkToExitIfUncaught)
|
private void |
replaceLocalsOnStack(int index,
TypeReference type)
Replaces copies of local <#index,type> with
newly-generated temporaries, and generates the necessary move instructions. |
private void |
setCurrentGuard(Operand guard)
|
static void |
setGuard(RegisterOperand rop,
Operand guard)
|
private void |
setLocal(int i,
Operand op)
Set the specified local variable |
private void |
setLocalDual(int i,
Operand op)
Set the specified local variable |
private InlineDecision |
shouldInline(Instruction call,
boolean isExtant,
int realBCI)
Should we inline a call site? |
private void |
start(GenerationContext context)
|
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final BC2IR.DummyStackSlot DUMMY
private GenerationContext gc
private BytecodeStream bcodes
private BBSet blocks
private int instrIndex
private boolean osrGuardedInline
private int bciAdjustment
private Instruction lastInstr
private boolean endOfBasicBlock
private boolean fallThrough
private BasicBlockLE currentBBLE
private OperandStack stack
private Operand[] _localState
private int runoff
private Operand currentGuard
private boolean inlinedSomething
private int param1
private int param2
private Instruction lastOsrBarrier
private static final boolean DBG_SELECTIVE
static final boolean DBG_SELECTED
Constructor Detail |
---|
private BC2IR()
private BC2IR(GenerationContext context)
context
- the context to generate HIR intoMethod Detail |
---|
public static void generateHIR(GenerationContext context)
This is the only external entry point to BC2IR.
Note: most clients should be calling methods in ConvertBCtoHIR or in Inliner rather than invoking BC2IR.generateHIR directly.
context
- the generation contextprivate void start(GenerationContext context)
private void finish(GenerationContext context)
private void generateHIR()
public Instruction generateAnewarray(TypeReference arrayTypeRef, TypeReference elementTypeRef)
private void generateFrom(int fromIndex)
fromIndex
- bytecode index to start fromprivate Instruction _unaryHelper(Operator operator, Operand val, TypeReference type)
private Instruction _unaryDualHelper(Operator operator, Operand val, TypeReference type)
private Instruction _binaryHelper(Operator operator, Operand op1, Operand op2, TypeReference type)
private Instruction _guardedBinaryHelper(Operator operator, Operand op1, Operand op2, Operand guard, TypeReference type)
private Instruction _binaryDualHelper(Operator operator, Operand op1, Operand op2, TypeReference type)
private Instruction _guardedBinaryDualHelper(Operator operator, Operand op1, Operand op2, Operand guard, TypeReference type)
private Instruction _moveHelper(Operator operator, Operand val, TypeReference type)
private Instruction _moveDualHelper(Operator operator, Operand val, TypeReference type)
public Instruction _aloadHelper(Operator operator, Operand ref, Operand index, TypeReference type)
private Instruction _callHelper(MethodReference meth, MethodOperand methOp)
private void _returnHelper(Operator operator, Operand val)
public void appendInstruction(Instruction s)
s
- instruction to appendvoid markBBUnsafeForScheduling()
private LocationOperand makeStaticFieldRef(FieldReference f)
f
- desired fieldprivate LocationOperand makeInstanceFieldRef(FieldReference f)
private TypeOperand makeTypeOperand(TypeReference type)
type
- desired typeprivate TypeOperand makeTypeOperand(RVMType type)
type
- desired typeprivate boolean couldCauseClassLoading(TypeReference typeRef)
public Operand getConstantOperand(int index)
private Instruction do_iload(int index)
index
- local variable numberprivate Instruction do_fload(int index)
index
- local variable numberprivate Instruction do_aload(int index)
index
- local variable numberprivate Instruction do_lload(int index)
index
- local variable numberprivate Instruction do_dload(int index)
index
- local variable numberprivate Instruction do_iinc(int index, int amount)
index
- local variable numberamount
- amount to increment byprivate Instruction do_store(int index, Operand op1)
index
- local variable numberprivate Instruction do_astore(int index)
index
- local variable numberpublic void push(Operand r)
r
- operand to pushvoid pushDual(Operand r)
r
- operand to pushvoid push(Operand r, TypeReference type)
r
- operand to pushtype
- data type of operandprivate Instruction pushCopy(Operand op1, int b1)
op1
- operand to pushb1
- bytecode index to associate with the pushed operandprivate Instruction pushCopy(Operand op1)
op1
- operand to pushOperand pop()
public Operand popInt()
Operand popFloat()
public Operand popRef()
public Operand popAddress()
Operand popLong()
Operand popDouble()
void popDummy()
Operand pop(TypeReference type)
private Operand popShiftInt(boolean longShift)
longShift
- is this a shift of a long
private Instruction _jsrHelper(int offset)
private Instruction _retHelper(int var)
public TypeReference getArrayTypeOf(Operand op)
op
- operand to get type ofprivate TypeReference getRefTypeOf(Operand op)
op
- operand to get type ofpublic void assertIsType(Operand op, TypeReference type)
op
- operand to checktype
- expected type of operandprivate void assertIsAssignable(TypeReference parentType, TypeReference childType)
parentType
- parent typechildType
- child typeprivate void db(String val)
val
- string to printprivate String printBlocks()
public static boolean isNonNull(Operand op)
public static boolean hasGuard(RegisterOperand rop)
public static boolean hasLessConservativeGuard(RegisterOperand rop1, RegisterOperand rop2)
public void markGuardlessNonNull(RegisterOperand rop)
public static Operand getGuard(Operand op)
public static void setGuard(RegisterOperand rop, Operand guard)
private void setCurrentGuard(Operand guard)
public void clearCurrentGuard()
public Operand getCurrentGuard()
public boolean do_NullCheck(Operand ref)
true
if an unconditional throw is generated, false
otherwisepublic boolean do_BoundsCheck(Operand ref, Operand index)
true
if an unconditional throw is generated, false
otherwiseprivate boolean do_IntZeroCheck(Operand div)
true
if an unconditional trap is generated, false
otherwiseprivate boolean do_LongZeroCheck(Operand div)
true
if an unconditional trap is generated, false
otherwiseprivate boolean do_CheckStore(Operand ref, Operand elem, TypeReference elemType)
ref
- the array referenceelem
- the element to be written to the arrayelemType
- the type of the array references elements
true
if an unconditional throw is generated, false
otherwiseprivate BasicBlockLE getOrCreateBlock(int target)
target
- target indexprivate BasicBlockLE getOrCreateBlock(int target, BasicBlockLE from, OperandStack simStack, Operand[] simLocals)
null
, rectifies stack state with target stack state.
If simLocals is non-null
, rectifies local state with target local state.
Any instructions needed to rectify stack/local state are appended to from.
If the target is between bcodes.index() and runoff, runoff is
updated to be target.
target
- target indexfrom
- the block from which control is being transfered
and to which stack rectification instructions are added.simStack
- stack state to rectify, or null
simLocals
- local state to rectify, or null
private BranchOperand generateTarget(int offset)
private Instruction _gotoHelper(int offset)
private Instruction _intIfHelper(ConditionOperand cond)
private Instruction _intIfCmpHelper(ConditionOperand cond)
private Instruction _refIfNullHelper(ConditionOperand cond)
private Instruction _refIfCmpHelper(ConditionOperand cond)
private void replaceLocalsOnStack(int index, TypeReference type)
<#index,type>
with
newly-generated temporaries, and generates the necessary move instructions.
index
- the local's indextype
- the local's typeprivate BasicBlock rectifyStateWithNullPtrExceptionHandler()
private BasicBlock rectifyStateWithArrayBoundsExceptionHandler()
private BasicBlock rectifyStateWithArithmeticExceptionHandler()
private BasicBlock rectifyStateWithArrayStoreExceptionHandler()
private BasicBlock rectifyStateWithErrorHandler()
public void rectifyStateWithExceptionHandlers()
public BasicBlock rectifyStateWithExceptionHandler(TypeReference exceptionType)
private BasicBlock rectifyStateWithNullPtrExceptionHandler(boolean linkToExitIfUncaught)
private BasicBlock rectifyStateWithArrayBoundsExceptionHandler(boolean linkToExitIfUncaught)
private BasicBlock rectifyStateWithArithmeticExceptionHandler(boolean linkToExitIfUncaught)
private BasicBlock rectifyStateWithArrayStoreExceptionHandler(boolean linkToExitIfUncaught)
private BasicBlock rectifyStateWithErrorHandler(boolean linkToExitIfUncaught)
private BasicBlock rectifyStateWithExceptionHandler(TypeReference exceptionType, boolean linkToExitIfUncaught)
private void rectifyStateWithExceptionHandlers(boolean linkToExitIfUncaught)
private InlineDecision shouldInline(Instruction call, boolean isExtant, int realBCI)
call
- the call instruction being considered for inliningisExtant
- is the receiver of a virtual method an extant object?realBCI
- the real bytecode index of the call instruction, not adjusted because of OSRprivate boolean maybeInlineMethod(InlineDecision inlDec, Instruction callSite)
inlDec
- the inline decision for this call sitecallSite
- the call instruction we are attempting to inline
true
if inlining succeeded, false
otherwiseprivate Instruction _createOsrBarrier()
private Operand _prepareLongConstant(Operand op)
private Operand _prepareDoubleConstant(Operand op)
private Operand _loadLocalForOSR(Operand op)
op
- the local variable.
public static Instruction _osrHelper(Instruction barrier)
private Operand getLocal(int i)
i
- local variable numberprivate Operand getLocalDual(int i)
i
- local variable numberprivate void setLocal(int i, Operand op)
i
- local variable numberop
- Operand to store in the localprivate void setLocalDual(int i, Operand op)
i
- local variable numberop
- Operand to store in the local
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |