use of org.graalvm.compiler.core.common.PermanentBailoutException in project graal by oracle.
the class BytecodeParser method processBytecode.
public final void processBytecode(int bci, int opcode) {
int cpi;
// Checkstyle: stop
switch(opcode) {
case NOP:
/* nothing to do */
break;
case ACONST_NULL:
frameState.push(JavaKind.Object, appendConstant(JavaConstant.NULL_POINTER));
break;
// fall through
case ICONST_M1:
// fall through
case ICONST_0:
// fall through
case ICONST_1:
// fall through
case ICONST_2:
// fall through
case ICONST_3:
// fall through
case ICONST_4:
case ICONST_5:
frameState.push(JavaKind.Int, appendConstant(JavaConstant.forInt(opcode - ICONST_0)));
break;
// fall through
case LCONST_0:
case LCONST_1:
frameState.push(JavaKind.Long, appendConstant(JavaConstant.forLong(opcode - LCONST_0)));
break;
// fall through
case FCONST_0:
// fall through
case FCONST_1:
case FCONST_2:
frameState.push(JavaKind.Float, appendConstant(JavaConstant.forFloat(opcode - FCONST_0)));
break;
// fall through
case DCONST_0:
case DCONST_1:
frameState.push(JavaKind.Double, appendConstant(JavaConstant.forDouble(opcode - DCONST_0)));
break;
case BIPUSH:
frameState.push(JavaKind.Int, appendConstant(JavaConstant.forInt(stream.readByte())));
break;
case SIPUSH:
frameState.push(JavaKind.Int, appendConstant(JavaConstant.forInt(stream.readShort())));
break;
// fall through
case LDC:
// fall through
case LDC_W:
case LDC2_W:
genLoadConstant(stream.readCPI(), opcode);
break;
case ILOAD:
loadLocal(stream.readLocalIndex(), JavaKind.Int);
break;
case LLOAD:
loadLocal(stream.readLocalIndex(), JavaKind.Long);
break;
case FLOAD:
loadLocal(stream.readLocalIndex(), JavaKind.Float);
break;
case DLOAD:
loadLocal(stream.readLocalIndex(), JavaKind.Double);
break;
case ALOAD:
loadLocalObject(stream.readLocalIndex());
break;
// fall through
case ILOAD_0:
// fall through
case ILOAD_1:
// fall through
case ILOAD_2:
case ILOAD_3:
loadLocal(opcode - ILOAD_0, JavaKind.Int);
break;
// fall through
case LLOAD_0:
// fall through
case LLOAD_1:
// fall through
case LLOAD_2:
case LLOAD_3:
loadLocal(opcode - LLOAD_0, JavaKind.Long);
break;
// fall through
case FLOAD_0:
// fall through
case FLOAD_1:
// fall through
case FLOAD_2:
case FLOAD_3:
loadLocal(opcode - FLOAD_0, JavaKind.Float);
break;
// fall through
case DLOAD_0:
// fall through
case DLOAD_1:
// fall through
case DLOAD_2:
case DLOAD_3:
loadLocal(opcode - DLOAD_0, JavaKind.Double);
break;
// fall through
case ALOAD_0:
// fall through
case ALOAD_1:
// fall through
case ALOAD_2:
case ALOAD_3:
loadLocalObject(opcode - ALOAD_0);
break;
case IALOAD:
genLoadIndexed(JavaKind.Int);
break;
case LALOAD:
genLoadIndexed(JavaKind.Long);
break;
case FALOAD:
genLoadIndexed(JavaKind.Float);
break;
case DALOAD:
genLoadIndexed(JavaKind.Double);
break;
case AALOAD:
genLoadIndexed(JavaKind.Object);
break;
case BALOAD:
genLoadIndexed(JavaKind.Byte);
break;
case CALOAD:
genLoadIndexed(JavaKind.Char);
break;
case SALOAD:
genLoadIndexed(JavaKind.Short);
break;
case ISTORE:
storeLocal(JavaKind.Int, stream.readLocalIndex());
break;
case LSTORE:
storeLocal(JavaKind.Long, stream.readLocalIndex());
break;
case FSTORE:
storeLocal(JavaKind.Float, stream.readLocalIndex());
break;
case DSTORE:
storeLocal(JavaKind.Double, stream.readLocalIndex());
break;
case ASTORE:
storeLocal(JavaKind.Object, stream.readLocalIndex());
break;
// fall through
case ISTORE_0:
// fall through
case ISTORE_1:
// fall through
case ISTORE_2:
case ISTORE_3:
storeLocal(JavaKind.Int, opcode - ISTORE_0);
break;
// fall through
case LSTORE_0:
// fall through
case LSTORE_1:
// fall through
case LSTORE_2:
case LSTORE_3:
storeLocal(JavaKind.Long, opcode - LSTORE_0);
break;
// fall through
case FSTORE_0:
// fall through
case FSTORE_1:
// fall through
case FSTORE_2:
case FSTORE_3:
storeLocal(JavaKind.Float, opcode - FSTORE_0);
break;
// fall through
case DSTORE_0:
// fall through
case DSTORE_1:
// fall through
case DSTORE_2:
case DSTORE_3:
storeLocal(JavaKind.Double, opcode - DSTORE_0);
break;
// fall through
case ASTORE_0:
// fall through
case ASTORE_1:
// fall through
case ASTORE_2:
case ASTORE_3:
storeLocal(JavaKind.Object, opcode - ASTORE_0);
break;
case IASTORE:
genStoreIndexed(JavaKind.Int);
break;
case LASTORE:
genStoreIndexed(JavaKind.Long);
break;
case FASTORE:
genStoreIndexed(JavaKind.Float);
break;
case DASTORE:
genStoreIndexed(JavaKind.Double);
break;
case AASTORE:
genStoreIndexed(JavaKind.Object);
break;
case BASTORE:
genStoreIndexed(JavaKind.Byte);
break;
case CASTORE:
genStoreIndexed(JavaKind.Char);
break;
case SASTORE:
genStoreIndexed(JavaKind.Short);
break;
// fall through
case POP:
// fall through
case POP2:
// fall through
case DUP:
// fall through
case DUP_X1:
// fall through
case DUP_X2:
// fall through
case DUP2:
// fall through
case DUP2_X1:
// fall through
case DUP2_X2:
case SWAP:
frameState.stackOp(opcode);
break;
// fall through
case IADD:
// fall through
case ISUB:
case IMUL:
genArithmeticOp(JavaKind.Int, opcode);
break;
// fall through
case IDIV:
case IREM:
genIntegerDivOp(JavaKind.Int, opcode);
break;
// fall through
case LADD:
// fall through
case LSUB:
case LMUL:
genArithmeticOp(JavaKind.Long, opcode);
break;
// fall through
case LDIV:
case LREM:
genIntegerDivOp(JavaKind.Long, opcode);
break;
// fall through
case FADD:
// fall through
case FSUB:
// fall through
case FMUL:
// fall through
case FDIV:
case FREM:
genArithmeticOp(JavaKind.Float, opcode);
break;
// fall through
case DADD:
// fall through
case DSUB:
// fall through
case DMUL:
// fall through
case DDIV:
case DREM:
genArithmeticOp(JavaKind.Double, opcode);
break;
case INEG:
genNegateOp(JavaKind.Int);
break;
case LNEG:
genNegateOp(JavaKind.Long);
break;
case FNEG:
genNegateOp(JavaKind.Float);
break;
case DNEG:
genNegateOp(JavaKind.Double);
break;
// fall through
case ISHL:
// fall through
case ISHR:
case IUSHR:
genShiftOp(JavaKind.Int, opcode);
break;
// fall through
case IAND:
// fall through
case IOR:
case IXOR:
genLogicOp(JavaKind.Int, opcode);
break;
// fall through
case LSHL:
// fall through
case LSHR:
case LUSHR:
genShiftOp(JavaKind.Long, opcode);
break;
// fall through
case LAND:
// fall through
case LOR:
case LXOR:
genLogicOp(JavaKind.Long, opcode);
break;
case IINC:
genIncrement();
break;
case I2F:
genFloatConvert(FloatConvert.I2F, JavaKind.Int, JavaKind.Float);
break;
case I2D:
genFloatConvert(FloatConvert.I2D, JavaKind.Int, JavaKind.Double);
break;
case L2F:
genFloatConvert(FloatConvert.L2F, JavaKind.Long, JavaKind.Float);
break;
case L2D:
genFloatConvert(FloatConvert.L2D, JavaKind.Long, JavaKind.Double);
break;
case F2I:
genFloatConvert(FloatConvert.F2I, JavaKind.Float, JavaKind.Int);
break;
case F2L:
genFloatConvert(FloatConvert.F2L, JavaKind.Float, JavaKind.Long);
break;
case F2D:
genFloatConvert(FloatConvert.F2D, JavaKind.Float, JavaKind.Double);
break;
case D2I:
genFloatConvert(FloatConvert.D2I, JavaKind.Double, JavaKind.Int);
break;
case D2L:
genFloatConvert(FloatConvert.D2L, JavaKind.Double, JavaKind.Long);
break;
case D2F:
genFloatConvert(FloatConvert.D2F, JavaKind.Double, JavaKind.Float);
break;
case L2I:
genNarrow(JavaKind.Long, JavaKind.Int);
break;
case I2L:
genSignExtend(JavaKind.Int, JavaKind.Long);
break;
case I2B:
genSignExtend(JavaKind.Byte, JavaKind.Int);
break;
case I2S:
genSignExtend(JavaKind.Short, JavaKind.Int);
break;
case I2C:
genZeroExtend(JavaKind.Char, JavaKind.Int);
break;
case LCMP:
genCompareOp(JavaKind.Long, false);
break;
case FCMPL:
genCompareOp(JavaKind.Float, true);
break;
case FCMPG:
genCompareOp(JavaKind.Float, false);
break;
case DCMPL:
genCompareOp(JavaKind.Double, true);
break;
case DCMPG:
genCompareOp(JavaKind.Double, false);
break;
case IFEQ:
genIfZero(Condition.EQ);
break;
case IFNE:
genIfZero(Condition.NE);
break;
case IFLT:
genIfZero(Condition.LT);
break;
case IFGE:
genIfZero(Condition.GE);
break;
case IFGT:
genIfZero(Condition.GT);
break;
case IFLE:
genIfZero(Condition.LE);
break;
case IF_ICMPEQ:
genIfSame(JavaKind.Int, Condition.EQ);
break;
case IF_ICMPNE:
genIfSame(JavaKind.Int, Condition.NE);
break;
case IF_ICMPLT:
genIfSame(JavaKind.Int, Condition.LT);
break;
case IF_ICMPGE:
genIfSame(JavaKind.Int, Condition.GE);
break;
case IF_ICMPGT:
genIfSame(JavaKind.Int, Condition.GT);
break;
case IF_ICMPLE:
genIfSame(JavaKind.Int, Condition.LE);
break;
case IF_ACMPEQ:
genIfSame(JavaKind.Object, Condition.EQ);
break;
case IF_ACMPNE:
genIfSame(JavaKind.Object, Condition.NE);
break;
case GOTO:
genGoto();
break;
case JSR:
genJsr(stream.readBranchDest());
break;
case RET:
genRet(stream.readLocalIndex());
break;
case TABLESWITCH:
genSwitch(new BytecodeTableSwitch(getStream(), bci()));
break;
case LOOKUPSWITCH:
genSwitch(new BytecodeLookupSwitch(getStream(), bci()));
break;
case IRETURN:
genReturn(frameState.pop(JavaKind.Int), JavaKind.Int);
break;
case LRETURN:
genReturn(frameState.pop(JavaKind.Long), JavaKind.Long);
break;
case FRETURN:
genReturn(frameState.pop(JavaKind.Float), JavaKind.Float);
break;
case DRETURN:
genReturn(frameState.pop(JavaKind.Double), JavaKind.Double);
break;
case ARETURN:
genReturn(frameState.pop(JavaKind.Object), JavaKind.Object);
break;
case RETURN:
genReturn(null, JavaKind.Void);
break;
case GETSTATIC:
cpi = stream.readCPI();
genGetStatic(cpi, opcode);
break;
case PUTSTATIC:
cpi = stream.readCPI();
genPutStatic(cpi, opcode);
break;
case GETFIELD:
cpi = stream.readCPI();
genGetField(cpi, opcode);
break;
case PUTFIELD:
cpi = stream.readCPI();
genPutField(cpi, opcode);
break;
case INVOKEVIRTUAL:
cpi = stream.readCPI();
genInvokeVirtual(cpi, opcode);
break;
case INVOKESPECIAL:
cpi = stream.readCPI();
genInvokeSpecial(cpi, opcode);
break;
case INVOKESTATIC:
cpi = stream.readCPI();
genInvokeStatic(cpi, opcode);
break;
case INVOKEINTERFACE:
cpi = stream.readCPI();
genInvokeInterface(cpi, opcode);
break;
case INVOKEDYNAMIC:
cpi = stream.readCPI4();
genInvokeDynamic(cpi, opcode);
break;
case NEW:
genNewInstance(stream.readCPI());
break;
case NEWARRAY:
genNewPrimitiveArray(stream.readLocalIndex());
break;
case ANEWARRAY:
genNewObjectArray(stream.readCPI());
break;
case ARRAYLENGTH:
genArrayLength();
break;
case ATHROW:
genThrow();
break;
case CHECKCAST:
genCheckCast();
break;
case INSTANCEOF:
genInstanceOf();
break;
case MONITORENTER:
genMonitorEnter(frameState.pop(JavaKind.Object), stream.nextBCI());
break;
case MONITOREXIT:
genMonitorExit(frameState.pop(JavaKind.Object), null, stream.nextBCI());
break;
case MULTIANEWARRAY:
genNewMultiArray(stream.readCPI());
break;
case IFNULL:
genIfNull(Condition.EQ);
break;
case IFNONNULL:
genIfNull(Condition.NE);
break;
case GOTO_W:
genGoto();
break;
case JSR_W:
genJsr(stream.readBranchDest());
break;
case BREAKPOINT:
throw new PermanentBailoutException("concurrent setting of breakpoint");
default:
throw new PermanentBailoutException("Unsupported opcode %d (%s) [bci=%d]", opcode, nameOf(opcode), bci);
}
// @formatter:on
// Checkstyle: resume
}
use of org.graalvm.compiler.core.common.PermanentBailoutException in project graal by oracle.
the class ReentrantBlockIterator method apply.
public static <StateT> EconomicMap<FixedNode, StateT> apply(BlockIteratorClosure<StateT> closure, Block start, StateT initialState, Predicate<Block> stopAtBlock) {
Deque<Block> blockQueue = new ArrayDeque<>();
/*
* States are stored on EndNodes before merges, and on BeginNodes after ControlSplitNodes.
*/
EconomicMap<FixedNode, StateT> states = EconomicMap.create(Equivalence.IDENTITY);
StateT state = initialState;
Block current = start;
StructuredGraph graph = start.getBeginNode().graph();
CompilationAlarm compilationAlarm = CompilationAlarm.current();
while (true) {
if (compilationAlarm.hasExpired()) {
int period = CompilationAlarm.Options.CompilationExpirationPeriod.getValue(graph.getOptions());
if (period > 120) {
throw new PermanentBailoutException("Compilation exceeded %d seconds during CFG traversal", period);
} else {
throw new RetryableBailoutException("Compilation exceeded %d seconds during CFG traversal", period);
}
}
Block next = null;
if (stopAtBlock != null && stopAtBlock.test(current)) {
states.put(current.getBeginNode(), state);
} else {
state = closure.processBlock(current, state);
Block[] successors = current.getSuccessors();
if (successors.length == 0) {
// nothing to do...
} else if (successors.length == 1) {
Block successor = successors[0];
if (successor.isLoopHeader()) {
if (current.isLoopEnd()) {
// nothing to do... loop ends only lead to loop begins we've already
// visited
states.put(current.getEndNode(), state);
} else {
recurseIntoLoop(closure, blockQueue, states, state, successor);
}
} else if (current.getEndNode() instanceof AbstractEndNode) {
AbstractEndNode end = (AbstractEndNode) current.getEndNode();
// add the end node and see if the merge is ready for processing
AbstractMergeNode merge = end.merge();
if (allEndsVisited(states, current, merge)) {
ArrayList<StateT> mergedStates = mergeStates(states, state, current, successor, merge);
state = closure.merge(successor, mergedStates);
next = successor;
} else {
assert !states.containsKey(end);
states.put(end, state);
}
} else {
next = successor;
}
} else {
next = processMultipleSuccessors(closure, blockQueue, states, state, successors);
}
}
// get next queued block
if (next != null) {
current = next;
} else if (blockQueue.isEmpty()) {
return states;
} else {
current = blockQueue.removeFirst();
assert current.getPredecessorCount() == 1;
assert states.containsKey(current.getBeginNode());
state = states.removeKey(current.getBeginNode());
}
}
}
use of org.graalvm.compiler.core.common.PermanentBailoutException in project graal by oracle.
the class LoopDetector method handleLoopExplosionBegin.
protected void handleLoopExplosionBegin(MethodScope methodScope, LoopScope loopScope, LoopBeginNode loopBegin) {
checkLoopExplosionIteration(methodScope, loopScope);
List<EndNode> predecessors = loopBegin.forwardEnds().snapshot();
FixedNode successor = loopBegin.next();
FrameState frameState = loopBegin.stateAfter();
if (methodScope.loopExplosion == LoopExplosionKind.MERGE_EXPLODE) {
LoopExplosionState queryState = new LoopExplosionState(frameState, null);
LoopExplosionState existingState = loopScope.iterationStates.get(queryState);
if (existingState != null) {
loopBegin.replaceAtUsagesAndDelete(existingState.merge);
successor.safeDelete();
for (EndNode predecessor : predecessors) {
existingState.merge.addForwardEnd(predecessor);
}
return;
}
}
MergeNode merge = graph.add(new MergeNode());
methodScope.loopExplosionMerges.add(merge);
if (methodScope.loopExplosion == LoopExplosionKind.MERGE_EXPLODE) {
if (loopScope.iterationStates.size() == 0 && loopScope.loopDepth == 1) {
if (methodScope.loopExplosionHead != null) {
throw new PermanentBailoutException("Graal implementation restriction: Method with %s loop explosion must not have more than one top-level loop", LoopExplosionKind.MERGE_EXPLODE);
}
methodScope.loopExplosionHead = merge;
}
List<ValueNode> newFrameStateValues = new ArrayList<>();
for (ValueNode frameStateValue : frameState.values) {
if (frameStateValue == null || frameStateValue.isConstant() || !graph.isNew(methodScope.methodStartMark, frameStateValue)) {
newFrameStateValues.add(frameStateValue);
} else {
ProxyPlaceholder newFrameStateValue = graph.unique(new ProxyPlaceholder(frameStateValue, merge));
newFrameStateValues.add(newFrameStateValue);
/*
* We do not have the orderID of the value anymore, so we need to search through
* the complete list of nodes to find a match.
*/
for (int i = 0; i < loopScope.createdNodes.length; i++) {
if (loopScope.createdNodes[i] == frameStateValue) {
loopScope.createdNodes[i] = newFrameStateValue;
}
}
if (loopScope.initialCreatedNodes != null) {
for (int i = 0; i < loopScope.initialCreatedNodes.length; i++) {
if (loopScope.initialCreatedNodes[i] == frameStateValue) {
loopScope.initialCreatedNodes[i] = newFrameStateValue;
}
}
}
}
}
FrameState newFrameState = graph.add(new FrameState(frameState.outerFrameState(), frameState.getCode(), frameState.bci, newFrameStateValues, frameState.localsSize(), frameState.stackSize(), frameState.rethrowException(), frameState.duringCall(), frameState.monitorIds(), frameState.virtualObjectMappings()));
frameState.replaceAtUsagesAndDelete(newFrameState);
frameState = newFrameState;
}
loopBegin.replaceAtUsagesAndDelete(merge);
merge.setStateAfter(frameState);
merge.setNext(successor);
for (EndNode predecessor : predecessors) {
merge.addForwardEnd(predecessor);
}
if (methodScope.loopExplosion == LoopExplosionKind.MERGE_EXPLODE) {
LoopExplosionState explosionState = new LoopExplosionState(frameState, merge);
loopScope.iterationStates.put(explosionState, explosionState);
}
}
use of org.graalvm.compiler.core.common.PermanentBailoutException in project graal by oracle.
the class PEGraphDecoder method tooManyLoopExplosionIterations.
private static RuntimeException tooManyLoopExplosionIterations(PEMethodScope methodScope, OptionValues options) {
String message = "too many loop explosion iterations - does the explosion not terminate for method " + methodScope.method + "?";
RuntimeException bailout = Options.FailedLoopExplosionIsFatal.getValue(options) ? new RuntimeException(message) : new PermanentBailoutException(message);
throw GraphUtil.createBailoutException(message, bailout, GraphUtil.approxSourceStackTraceElement(methodScope.getCallerBytecodePosition()));
}
use of org.graalvm.compiler.core.common.PermanentBailoutException in project graal by oracle.
the class LinearScanLifetimeAnalysisPhase method computeLocalLiveSets.
/**
* Computes local live sets (i.e. {@link BlockData#liveGen} and {@link BlockData#liveKill})
* separately for each block.
*/
@SuppressWarnings("try")
void computeLocalLiveSets() {
int liveSize = allocator.liveSetSize();
intervalInLoop = new BitMap2D(allocator.operandSize(), allocator.numLoops());
try {
// iterate all blocks
for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) {
try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) {
final BitSet liveGen = new BitSet(liveSize);
final BitSet liveKill = new BitSet(liveSize);
ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
int numInst = instructions.size();
ValueConsumer useConsumer = (operand, mode, flags) -> {
if (isVariable(operand)) {
int operandNum = allocator.operandNumber(operand);
if (!liveKill.get(operandNum)) {
liveGen.set(operandNum);
if (debug.isLogEnabled()) {
debug.log("liveGen for operand %d(%s)", operandNum, operand);
}
}
if (block.getLoop() != null) {
intervalInLoop.setBit(operandNum, block.getLoop().getIndex());
}
}
if (allocator.detailedAsserts) {
verifyInput(block, liveKill, operand);
}
};
ValueConsumer stateConsumer = (operand, mode, flags) -> {
if (LinearScan.isVariableOrRegister(operand)) {
int operandNum = allocator.operandNumber(operand);
if (!liveKill.get(operandNum)) {
liveGen.set(operandNum);
if (debug.isLogEnabled()) {
debug.log("liveGen in state for operand %d(%s)", operandNum, operand);
}
}
}
};
ValueConsumer defConsumer = (operand, mode, flags) -> {
if (isVariable(operand)) {
int varNum = allocator.operandNumber(operand);
liveKill.set(varNum);
if (debug.isLogEnabled()) {
debug.log("liveKill for operand %d(%s)", varNum, operand);
}
if (block.getLoop() != null) {
intervalInLoop.setBit(varNum, block.getLoop().getIndex());
}
}
if (allocator.detailedAsserts) {
/*
* Fixed intervals are never live at block boundaries, so they need not
* be processed in live sets. Process them only in debug mode so that
* this can be checked
*/
verifyTemp(liveKill, operand);
}
};
// iterate all instructions of the block
for (int j = 0; j < numInst; j++) {
final LIRInstruction op = instructions.get(j);
try (Indent indent2 = debug.logAndIndent("handle op %d: %s", op.id(), op)) {
op.visitEachInput(useConsumer);
op.visitEachAlive(useConsumer);
/*
* Add uses of live locals from interpreter's point of view for proper
* debug information generation.
*/
op.visitEachState(stateConsumer);
op.visitEachTemp(defConsumer);
op.visitEachOutput(defConsumer);
}
}
// end of instruction iteration
BlockData blockSets = allocator.getBlockData(block);
blockSets.liveGen = liveGen;
blockSets.liveKill = liveKill;
blockSets.liveIn = new BitSet(liveSize);
blockSets.liveOut = new BitSet(liveSize);
if (debug.isLogEnabled()) {
debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen);
debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill);
}
}
}
// end of block iteration
} catch (OutOfMemoryError oom) {
throw new PermanentBailoutException(oom, "Out-of-memory during live set allocation of size %d", liveSize);
}
}
Aggregations