use of com.oracle.truffle.api.exception.AbstractTruffleException in project graal by oracle.
the class BytecodeNode method executeBodyFromBCI.
@ExplodeLoop(kind = ExplodeLoop.LoopExplosionKind.MERGE_EXPLODE)
Object executeBodyFromBCI(VirtualFrame frame, int startBCI, int startTop, int startStatementIndex, boolean startSkipEntryInstrumentation) {
CompilerAsserts.partialEvaluationConstant(startBCI);
int curBCI = startBCI;
int top = startTop;
final InstrumentationSupport instrument = this.instrumentation;
int statementIndex = InstrumentationSupport.NO_STATEMENT;
int nextStatementIndex = startStatementIndex;
boolean skipEntryInstrumentation = startSkipEntryInstrumentation;
// so force the initialization here
if (!frame.isInt(EspressoFrame.BCI_SLOT)) {
initializeBody(frame);
}
final Counter loopCount = new Counter();
setBCI(frame, curBCI);
if (instrument != null && !skipEntryInstrumentation) {
instrument.notifyEntry(frame, this);
}
// the method from the beginning hence onStart is not applicable
if (startBCI == 0) {
livenessAnalysis.onStart(frame);
}
loop: while (true) {
final int curOpcode = bs.opcode(curBCI);
EXECUTED_BYTECODES_COUNT.inc();
try {
CompilerAsserts.partialEvaluationConstant(top);
CompilerAsserts.partialEvaluationConstant(curBCI);
CompilerAsserts.partialEvaluationConstant(skipEntryInstrumentation);
CompilerAsserts.partialEvaluationConstant(curOpcode);
CompilerAsserts.partialEvaluationConstant(statementIndex);
CompilerAsserts.partialEvaluationConstant(nextStatementIndex);
if (instrument != null || Bytecodes.canTrap(curOpcode)) {
/*
* curOpcode can be == WIDE, but none of the WIDE-prefixed bytecodes throw
* exceptions.
*/
setBCI(frame, curBCI);
}
if (instrument != null) {
if (!skipEntryInstrumentation) {
instrument.notifyStatement(frame, statementIndex, nextStatementIndex);
}
skipEntryInstrumentation = false;
statementIndex = nextStatementIndex;
}
// @formatter:off
switch(curOpcode) {
case NOP:
break;
case ACONST_NULL:
putObject(frame, top, StaticObject.NULL);
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:
putInt(frame, top, curOpcode - ICONST_0);
break;
// fall through
case LCONST_0:
case LCONST_1:
putLong(frame, top, curOpcode - LCONST_0);
break;
// fall through
case FCONST_0:
// fall through
case FCONST_1:
case FCONST_2:
putFloat(frame, top, curOpcode - FCONST_0);
break;
// fall through
case DCONST_0:
case DCONST_1:
putDouble(frame, top, curOpcode - DCONST_0);
break;
case BIPUSH:
putInt(frame, top, bs.readByte(curBCI));
break;
case SIPUSH:
putInt(frame, top, bs.readShort(curBCI));
break;
// fall through
case LDC:
// fall through
case LDC_W:
case LDC2_W:
putPoolConstant(frame, top, readCPI(curBCI), curOpcode);
break;
case ILOAD:
putInt(frame, top, getLocalInt(frame, bs.readLocalIndex(curBCI)));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case LLOAD:
putLong(frame, top, getLocalLong(frame, bs.readLocalIndex(curBCI)));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case FLOAD:
putFloat(frame, top, getLocalFloat(frame, bs.readLocalIndex(curBCI)));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case DLOAD:
putDouble(frame, top, getLocalDouble(frame, bs.readLocalIndex(curBCI)));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case ALOAD:
putObject(frame, top, getLocalObject(frame, bs.readLocalIndex(curBCI)));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case ILOAD_0:
// fall through
case ILOAD_1:
// fall through
case ILOAD_2:
case ILOAD_3:
putInt(frame, top, getLocalInt(frame, curOpcode - ILOAD_0));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case LLOAD_0:
// fall through
case LLOAD_1:
// fall through
case LLOAD_2:
case LLOAD_3:
putLong(frame, top, getLocalLong(frame, curOpcode - LLOAD_0));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case FLOAD_0:
// fall through
case FLOAD_1:
// fall through
case FLOAD_2:
case FLOAD_3:
putFloat(frame, top, getLocalFloat(frame, curOpcode - FLOAD_0));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case DLOAD_0:
// fall through
case DLOAD_1:
// fall through
case DLOAD_2:
case DLOAD_3:
putDouble(frame, top, getLocalDouble(frame, curOpcode - DLOAD_0));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case ALOAD_0:
putObject(frame, top, getLocalObject(frame, 0));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case ALOAD_1:
// fall through
case ALOAD_2:
case ALOAD_3:
putObject(frame, top, getLocalObject(frame, curOpcode - ALOAD_0));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case IALOAD:
// fall through
case LALOAD:
// fall through
case FALOAD:
// fall through
case DALOAD:
// fall through
case BALOAD:
// fall through
case CALOAD:
case SALOAD:
arrayLoad(frame, top, curBCI, curOpcode);
break;
case AALOAD:
arrayLoad(frame, top, curBCI, AALOAD);
checkNoForeignObjectAssumption(peekObject(frame, top - 2));
break;
case ISTORE:
setLocalInt(frame, bs.readLocalIndex(curBCI), popInt(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case LSTORE:
setLocalLong(frame, bs.readLocalIndex(curBCI), popLong(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case FSTORE:
setLocalFloat(frame, bs.readLocalIndex(curBCI), popFloat(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case DSTORE:
setLocalDouble(frame, bs.readLocalIndex(curBCI), popDouble(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case ASTORE:
setLocalObjectOrReturnAddress(frame, bs.readLocalIndex(curBCI), popReturnAddressOrObject(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case ISTORE_0:
// fall through
case ISTORE_1:
// fall through
case ISTORE_2:
case ISTORE_3:
setLocalInt(frame, curOpcode - ISTORE_0, popInt(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case LSTORE_0:
// fall through
case LSTORE_1:
// fall through
case LSTORE_2:
case LSTORE_3:
setLocalLong(frame, curOpcode - LSTORE_0, popLong(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case FSTORE_0:
// fall through
case FSTORE_1:
// fall through
case FSTORE_2:
case FSTORE_3:
setLocalFloat(frame, curOpcode - FSTORE_0, popFloat(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case DSTORE_0:
// fall through
case DSTORE_1:
// fall through
case DSTORE_2:
case DSTORE_3:
setLocalDouble(frame, curOpcode - DSTORE_0, popDouble(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case ASTORE_0:
// fall through
case ASTORE_1:
// fall through
case ASTORE_2:
case ASTORE_3:
setLocalObjectOrReturnAddress(frame, curOpcode - ASTORE_0, popReturnAddressOrObject(frame, top - 1));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
// fall through
case IASTORE:
// fall through
case LASTORE:
// fall through
case FASTORE:
// fall through
case DASTORE:
// fall through
case AASTORE:
// fall through
case BASTORE:
// fall through
case CASTORE:
case SASTORE:
arrayStore(frame, top, curBCI, curOpcode);
break;
case POP2:
clear(frame, top - 1);
clear(frame, top - 2);
break;
case POP:
clear(frame, top - 1);
break;
// TODO(peterssen): Stack shuffling is expensive.
case DUP:
EspressoFrame.dup1(frame, top);
break;
case DUP_X1:
EspressoFrame.dupx1(frame, top);
break;
case DUP_X2:
EspressoFrame.dupx2(frame, top);
break;
case DUP2:
EspressoFrame.dup2(frame, top);
break;
case DUP2_X1:
EspressoFrame.dup2x1(frame, top);
break;
case DUP2_X2:
EspressoFrame.dup2x2(frame, top);
break;
case SWAP:
EspressoFrame.swapSingle(frame, top);
break;
case IADD:
putInt(frame, top - 2, popInt(frame, top - 1) + popInt(frame, top - 2));
break;
case LADD:
putLong(frame, top - 4, popLong(frame, top - 1) + popLong(frame, top - 3));
break;
case FADD:
putFloat(frame, top - 2, popFloat(frame, top - 1) + popFloat(frame, top - 2));
break;
case DADD:
putDouble(frame, top - 4, popDouble(frame, top - 1) + popDouble(frame, top - 3));
break;
case ISUB:
putInt(frame, top - 2, popInt(frame, top - 2) - popInt(frame, top - 1));
break;
case LSUB:
putLong(frame, top - 4, popLong(frame, top - 3) - popLong(frame, top - 1));
break;
case FSUB:
putFloat(frame, top - 2, popFloat(frame, top - 2) - popFloat(frame, top - 1));
break;
case DSUB:
putDouble(frame, top - 4, popDouble(frame, top - 3) - popDouble(frame, top - 1));
break;
case IMUL:
putInt(frame, top - 2, popInt(frame, top - 1) * popInt(frame, top - 2));
break;
case LMUL:
putLong(frame, top - 4, popLong(frame, top - 1) * popLong(frame, top - 3));
break;
case FMUL:
putFloat(frame, top - 2, popFloat(frame, top - 1) * popFloat(frame, top - 2));
break;
case DMUL:
putDouble(frame, top - 4, popDouble(frame, top - 1) * popDouble(frame, top - 3));
break;
case IDIV:
putInt(frame, top - 2, divInt(checkNonZero(popInt(frame, top - 1)), popInt(frame, top - 2)));
break;
case LDIV:
putLong(frame, top - 4, divLong(checkNonZero(popLong(frame, top - 1)), popLong(frame, top - 3)));
break;
case FDIV:
putFloat(frame, top - 2, divFloat(popFloat(frame, top - 1), popFloat(frame, top - 2)));
break;
case DDIV:
putDouble(frame, top - 4, divDouble(popDouble(frame, top - 1), popDouble(frame, top - 3)));
break;
case IREM:
putInt(frame, top - 2, remInt(checkNonZero(popInt(frame, top - 1)), popInt(frame, top - 2)));
break;
case LREM:
putLong(frame, top - 4, remLong(checkNonZero(popLong(frame, top - 1)), popLong(frame, top - 3)));
break;
case FREM:
putFloat(frame, top - 2, remFloat(popFloat(frame, top - 1), popFloat(frame, top - 2)));
break;
case DREM:
putDouble(frame, top - 4, remDouble(popDouble(frame, top - 1), popDouble(frame, top - 3)));
break;
case INEG:
putInt(frame, top - 1, -popInt(frame, top - 1));
break;
case LNEG:
putLong(frame, top - 2, -popLong(frame, top - 1));
break;
case FNEG:
putFloat(frame, top - 1, -popFloat(frame, top - 1));
break;
case DNEG:
putDouble(frame, top - 2, -popDouble(frame, top - 1));
break;
case ISHL:
putInt(frame, top - 2, shiftLeftInt(popInt(frame, top - 1), popInt(frame, top - 2)));
break;
case LSHL:
putLong(frame, top - 3, shiftLeftLong(popInt(frame, top - 1), popLong(frame, top - 2)));
break;
case ISHR:
putInt(frame, top - 2, shiftRightSignedInt(popInt(frame, top - 1), popInt(frame, top - 2)));
break;
case LSHR:
putLong(frame, top - 3, shiftRightSignedLong(popInt(frame, top - 1), popLong(frame, top - 2)));
break;
case IUSHR:
putInt(frame, top - 2, shiftRightUnsignedInt(popInt(frame, top - 1), popInt(frame, top - 2)));
break;
case LUSHR:
putLong(frame, top - 3, shiftRightUnsignedLong(popInt(frame, top - 1), popLong(frame, top - 2)));
break;
case IAND:
putInt(frame, top - 2, popInt(frame, top - 1) & popInt(frame, top - 2));
break;
case LAND:
putLong(frame, top - 4, popLong(frame, top - 1) & popLong(frame, top - 3));
break;
case IOR:
putInt(frame, top - 2, popInt(frame, top - 1) | popInt(frame, top - 2));
break;
case LOR:
putLong(frame, top - 4, popLong(frame, top - 1) | popLong(frame, top - 3));
break;
case IXOR:
putInt(frame, top - 2, popInt(frame, top - 1) ^ popInt(frame, top - 2));
break;
case LXOR:
putLong(frame, top - 4, popLong(frame, top - 1) ^ popLong(frame, top - 3));
break;
case IINC:
setLocalInt(frame, bs.readLocalIndex1(curBCI), getLocalInt(frame, bs.readLocalIndex1(curBCI)) + bs.readIncrement1(curBCI));
livenessAnalysis.performPostBCI(frame, curBCI);
break;
case I2L:
putLong(frame, top - 1, popInt(frame, top - 1));
break;
case I2F:
putFloat(frame, top - 1, popInt(frame, top - 1));
break;
case I2D:
putDouble(frame, top - 1, popInt(frame, top - 1));
break;
case L2I:
putInt(frame, top - 2, (int) popLong(frame, top - 1));
break;
case L2F:
putFloat(frame, top - 2, popLong(frame, top - 1));
break;
case L2D:
putDouble(frame, top - 2, popLong(frame, top - 1));
break;
case F2I:
putInt(frame, top - 1, (int) popFloat(frame, top - 1));
break;
case F2L:
putLong(frame, top - 1, (long) popFloat(frame, top - 1));
break;
case F2D:
putDouble(frame, top - 1, popFloat(frame, top - 1));
break;
case D2I:
putInt(frame, top - 2, (int) popDouble(frame, top - 1));
break;
case D2L:
putLong(frame, top - 2, (long) popDouble(frame, top - 1));
break;
case D2F:
putFloat(frame, top - 2, (float) popDouble(frame, top - 1));
break;
case I2B:
putInt(frame, top - 1, (byte) popInt(frame, top - 1));
break;
case I2C:
putInt(frame, top - 1, (char) popInt(frame, top - 1));
break;
case I2S:
putInt(frame, top - 1, (short) popInt(frame, top - 1));
break;
case LCMP:
putInt(frame, top - 4, compareLong(popLong(frame, top - 1), popLong(frame, top - 3)));
break;
case FCMPL:
putInt(frame, top - 2, compareFloatLess(popFloat(frame, top - 1), popFloat(frame, top - 2)));
break;
case FCMPG:
putInt(frame, top - 2, compareFloatGreater(popFloat(frame, top - 1), popFloat(frame, top - 2)));
break;
case DCMPL:
putInt(frame, top - 4, compareDoubleLess(popDouble(frame, top - 1), popDouble(frame, top - 3)));
break;
case DCMPG:
putInt(frame, top - 4, compareDoubleGreater(popDouble(frame, top - 1), popDouble(frame, top - 3)));
break;
// fall through
case IFEQ:
// fall through
case IFNE:
// fall through
case IFLT:
// fall through
case IFGE:
// fall through
case IFGT:
case // fall through
IFLE:
if (takeBranchPrimitive1(popInt(frame, top - 1), curOpcode)) {
int targetBCI = bs.readBranchDest2(curBCI);
top += Bytecodes.stackEffectOf(IFLE);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
break;
// fall through
case IF_ICMPEQ:
// fall through
case IF_ICMPNE:
// fall through
case IF_ICMPLT:
// fall through
case IF_ICMPGE:
// fall through
case IF_ICMPGT:
case IF_ICMPLE:
if (takeBranchPrimitive2(popInt(frame, top - 1), popInt(frame, top - 2), curOpcode)) {
top += Bytecodes.stackEffectOf(IF_ICMPLE);
nextStatementIndex = beforeJumpChecks(frame, curBCI, bs.readBranchDest2(curBCI), top, statementIndex, instrument, loopCount);
curBCI = bs.readBranchDest2(curBCI);
continue loop;
}
break;
// fall through
case IF_ACMPEQ:
case IF_ACMPNE:
if (takeBranchRef2(popObject(frame, top - 1), popObject(frame, top - 2), curOpcode)) {
int targetBCI = bs.readBranchDest2(curBCI);
top += Bytecodes.stackEffectOf(IF_ACMPNE);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
break;
// fall through
case IFNULL:
case IFNONNULL:
if (takeBranchRef1(popObject(frame, top - 1), curOpcode)) {
int targetBCI = bs.readBranchDest2(curBCI);
top += Bytecodes.stackEffectOf(IFNONNULL);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
break;
case GOTO:
{
int targetBCI = bs.readBranchDest2(curBCI);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
case GOTO_W:
{
int targetBCI = bs.readBranchDest4(curBCI);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
case JSR:
{
putReturnAddress(frame, top, bs.nextBCI(curBCI));
int targetBCI = bs.readBranchDest2(curBCI);
top += Bytecodes.stackEffectOf(JSR);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
case JSR_W:
{
putReturnAddress(frame, top, bs.nextBCI(curBCI));
int targetBCI = bs.readBranchDest4(curBCI);
top += Bytecodes.stackEffectOf(JSR_W);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
case RET:
{
int targetBCI = getLocalReturnAddress(frame, bs.readLocalIndex1(curBCI));
livenessAnalysis.performPostBCI(frame, curBCI);
if (jsrBci == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
jsrBci = new int[bs.endBCI()][];
}
if (jsrBci[curBCI] == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
jsrBci[curBCI] = new int[] { targetBCI };
}
for (int jsr : jsrBci[curBCI]) {
if (jsr == targetBCI) {
CompilerAsserts.partialEvaluationConstant(jsr);
targetBCI = jsr;
top += Bytecodes.stackEffectOf(RET);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
}
CompilerDirectives.transferToInterpreterAndInvalidate();
jsrBci[curBCI] = Arrays.copyOf(jsrBci[curBCI], jsrBci[curBCI].length + 1);
jsrBci[curBCI][jsrBci[curBCI].length - 1] = targetBCI;
top += Bytecodes.stackEffectOf(RET);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
case TABLESWITCH:
{
int index = popInt(frame, top - 1);
BytecodeTableSwitch switchHelper = BytecodeTableSwitch.INSTANCE;
int low = switchHelper.lowKey(bs, curBCI);
int high = switchHelper.highKey(bs, curBCI);
assert low <= high;
// Interpreter uses direct lookup.
if (CompilerDirectives.inInterpreter()) {
int targetBCI;
if (low <= index && index <= high) {
targetBCI = switchHelper.targetAt(bs, curBCI, index - low);
} else {
targetBCI = switchHelper.defaultTarget(bs, curBCI);
}
top += Bytecodes.stackEffectOf(TABLESWITCH);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
// This loops take that into account.
for (int i = low; i != high + 1; ++i) {
if (i == index) {
// Key found.
int targetBCI = switchHelper.targetAt(bs, curBCI, i - low);
top += Bytecodes.stackEffectOf(TABLESWITCH);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
}
// Key not found.
int targetBCI = switchHelper.defaultTarget(bs, curBCI);
top += Bytecodes.stackEffectOf(TABLESWITCH);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
case LOOKUPSWITCH:
{
int key = popInt(frame, top - 1);
BytecodeLookupSwitch switchHelper = BytecodeLookupSwitch.INSTANCE;
int low = 0;
int high = switchHelper.numberOfCases(bs, curBCI) - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = switchHelper.keyAt(bs, curBCI, mid);
if (midVal < key) {
low = mid + 1;
} else if (midVal > key) {
high = mid - 1;
} else {
// Key found.
int targetBCI = curBCI + switchHelper.offsetAt(bs, curBCI, mid);
top += Bytecodes.stackEffectOf(LOOKUPSWITCH);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
}
// Key not found.
int targetBCI = switchHelper.defaultTarget(bs, curBCI);
top += Bytecodes.stackEffectOf(LOOKUPSWITCH);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
// fall through
case IRETURN:
// fall through
case LRETURN:
// fall through
case FRETURN:
// fall through
case DRETURN:
// fall through
case ARETURN:
case RETURN:
{
if (CompilerDirectives.hasNextTier() && loopCount.value > 0) {
LoopNode.reportLoopCount(this, loopCount.value);
}
Object returnValue = getReturnValueAsObject(frame, top);
if (instrument != null) {
instrument.notifyReturn(frame, statementIndex, returnValue);
}
return returnValue;
}
// fall through
case GETSTATIC:
case GETFIELD:
top += getField(frame, top, resolveField(curOpcode, /* Quickenable -> read from original code for thread safety */
readOriginalCPI(curBCI)), curBCI, curOpcode, statementIndex);
break;
// fall through
case PUTSTATIC:
case PUTFIELD:
top += putField(frame, top, resolveField(curOpcode, /* Quickenable -> read from original code for thread safety */
readOriginalCPI(curBCI)), curBCI, curOpcode, statementIndex);
break;
// fall through
case INVOKEVIRTUAL:
// fall through
case INVOKESPECIAL:
// fall through
case INVOKESTATIC:
case INVOKEINTERFACE:
top += quickenInvoke(frame, top, curBCI, curOpcode, statementIndex);
break;
case NEW:
putObject(frame, top, InterpreterToVM.newObject(resolveType(NEW, readCPI(curBCI)), true));
break;
case NEWARRAY:
putObject(frame, top - 1, InterpreterToVM.allocatePrimitiveArray(bs.readByte(curBCI), popInt(frame, top - 1), getMeta(), this));
break;
case ANEWARRAY:
putObject(frame, top - 1, InterpreterToVM.newReferenceArray(resolveType(ANEWARRAY, readCPI(curBCI)), popInt(frame, top - 1), this));
break;
case ARRAYLENGTH:
arrayLength(frame, top, curBCI);
break;
case ATHROW:
throw getMeta().throwException(nullCheck(popObject(frame, top - 1)));
case CHECKCAST:
top += quickenCheckCast(frame, top, curBCI, CHECKCAST);
break;
case INSTANCEOF:
top += quickenInstanceOf(frame, top, curBCI, INSTANCEOF);
break;
case MONITORENTER:
getRoot().monitorEnter(frame, nullCheck(popObject(frame, top - 1)));
break;
case MONITOREXIT:
getRoot().monitorExit(frame, nullCheck(popObject(frame, top - 1)));
break;
case WIDE:
{
int wideOpcode = bs.opcode(curBCI + 1);
switch(wideOpcode) {
case ILOAD:
putInt(frame, top, getLocalInt(frame, bs.readLocalIndex2(curBCI)));
break;
case LLOAD:
putLong(frame, top, getLocalLong(frame, bs.readLocalIndex2(curBCI)));
break;
case FLOAD:
putFloat(frame, top, getLocalFloat(frame, bs.readLocalIndex2(curBCI)));
break;
case DLOAD:
putDouble(frame, top, getLocalDouble(frame, bs.readLocalIndex2(curBCI)));
break;
case ALOAD:
putObject(frame, top, getLocalObject(frame, bs.readLocalIndex2(curBCI)));
break;
case ISTORE:
setLocalInt(frame, bs.readLocalIndex2(curBCI), popInt(frame, top - 1));
break;
case LSTORE:
setLocalLong(frame, bs.readLocalIndex2(curBCI), popLong(frame, top - 1));
break;
case FSTORE:
setLocalFloat(frame, bs.readLocalIndex2(curBCI), popFloat(frame, top - 1));
break;
case DSTORE:
setLocalDouble(frame, bs.readLocalIndex2(curBCI), popDouble(frame, top - 1));
break;
case ASTORE:
setLocalObjectOrReturnAddress(frame, bs.readLocalIndex2(curBCI), popReturnAddressOrObject(frame, top - 1));
break;
case IINC:
setLocalInt(frame, bs.readLocalIndex2(curBCI), getLocalInt(frame, bs.readLocalIndex2(curBCI)) + bs.readIncrement2(curBCI));
break;
case RET:
{
int targetBCI = getLocalReturnAddress(frame, bs.readLocalIndex2(curBCI));
livenessAnalysis.performPostBCI(frame, curBCI);
if (jsrBci == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
jsrBci = new int[bs.endBCI()][];
}
if (jsrBci[curBCI] == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
jsrBci[curBCI] = new int[] { targetBCI };
}
for (int jsr : jsrBci[curBCI]) {
if (jsr == targetBCI) {
CompilerAsserts.partialEvaluationConstant(jsr);
targetBCI = jsr;
top += Bytecodes.stackEffectOf(RET);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
}
CompilerDirectives.transferToInterpreterAndInvalidate();
jsrBci[curBCI] = Arrays.copyOf(jsrBci[curBCI], jsrBci[curBCI].length + 1);
jsrBci[curBCI][jsrBci[curBCI].length - 1] = targetBCI;
top += Bytecodes.stackEffectOf(RET);
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
continue loop;
}
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.shouldNotReachHere(Bytecodes.nameOf(curOpcode));
}
livenessAnalysis.performPostBCI(frame, curBCI);
int targetBCI = bs.nextBCI(curBCI);
livenessAnalysis.performOnEdge(frame, curBCI, targetBCI);
top += Bytecodes.stackEffectOf(wideOpcode);
curBCI = targetBCI;
continue loop;
}
case MULTIANEWARRAY:
top += allocateMultiArray(frame, top, resolveType(MULTIANEWARRAY, readCPI(curBCI)), bs.readUByte(curBCI + 3));
break;
case BREAKPOINT:
CompilerDirectives.transferToInterpreter();
throw EspressoError.unimplemented(Bytecodes.nameOf(curOpcode) + " not supported.");
case INVOKEDYNAMIC:
top += quickenInvokeDynamic(frame, top, curBCI, INVOKEDYNAMIC);
break;
case QUICK:
{
// Force a volatile read of the opcode.
if (bs.currentVolatileBC(curBCI) != QUICK) {
// Possible case of read reordering. Retry handling the bytecode to make sure we get a correct CPI.
CompilerDirectives.transferToInterpreterAndInvalidate();
continue loop;
}
BaseQuickNode quickNode = nodes[readCPI(curBCI)];
if (quickNode.removedByRedefintion()) {
CompilerDirectives.transferToInterpreterAndInvalidate();
quickNode = getBaseQuickNode(curBCI, top, statementIndex, quickNode);
}
top += quickNode.execute(frame);
break;
}
case SLIM_QUICK:
top += sparseNodes[curBCI].execute(frame);
break;
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.shouldNotReachHere(Bytecodes.nameOf(curOpcode));
}
// @formatter:on
} catch (AbstractTruffleException | StackOverflowError | OutOfMemoryError e) {
if (instrument != null && e instanceof EspressoException) {
instrument.notifyExceptionAt(frame, e, statementIndex);
}
CompilerAsserts.partialEvaluationConstant(curBCI);
// Handle both guest and host StackOverflowError.
if (e == getContext().getStackOverflow() || e instanceof StackOverflowError) {
// Always deopt on SOE.
CompilerDirectives.transferToInterpreter();
EspressoException wrappedStackOverflowError = null;
if (e == getContext().getStackOverflow()) {
wrappedStackOverflowError = (EspressoException) e;
} else {
wrappedStackOverflowError = getContext().getStackOverflow();
}
/*
* Stack Overflow management. All calls to stack manipulation are manually
* inlined to prevent another SOE.
*
* Note: no need to check for the stacktrace being null, as we reset the frames
* at each apparition of a host SOE.
*/
if (stackOverflowErrorInfo != null) {
for (int i = 0; i < stackOverflowErrorInfo.length; i += 3) {
if (curBCI >= stackOverflowErrorInfo[i] && curBCI < stackOverflowErrorInfo[i + 1]) {
clearOperandStack(frame, top);
top = EspressoFrame.VALUES_START + getMethodVersion().getCodeAttribute().getMaxLocals();
putObject(frame, top, wrappedStackOverflowError.getGuestException());
top++;
int targetBCI = stackOverflowErrorInfo[i + 2];
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
// skip bs.next()
continue loop;
}
}
}
if (instrument != null) {
instrument.notifyExceptionAt(frame, wrappedStackOverflowError, statementIndex);
}
if (CompilerDirectives.hasNextTier() && loopCount.value > 0) {
LoopNode.reportLoopCount(this, loopCount.value);
}
throw wrappedStackOverflowError;
} else /* EspressoException or AbstractTruffleException or OutOfMemoryError */
{
EspressoException wrappedException;
if (e instanceof EspressoException) {
wrappedException = (EspressoException) e;
} else if (e instanceof AbstractTruffleException) {
if (e instanceof EspressoExitException) {
CompilerDirectives.transferToInterpreter();
getRoot().abortMonitor(frame);
// Tearing down the VM, no need to report loop count.
throw e;
}
assert getContext().Polyglot;
// should fold
getMeta().polyglot.ForeignException.safeInitialize();
wrappedException = EspressoException.wrap(StaticObject.createForeignException(getMeta(), e, InteropLibrary.getUncached(e)), getMeta());
} else {
assert e instanceof OutOfMemoryError;
CompilerDirectives.transferToInterpreter();
wrappedException = getContext().getOutOfMemory();
}
ExceptionHandler[] handlers = getMethodVersion().getExceptionHandlers();
ExceptionHandler handler = null;
for (ExceptionHandler toCheck : handlers) {
CompilerAsserts.partialEvaluationConstant(toCheck);
if (curBCI >= toCheck.getStartBCI() && curBCI < toCheck.getEndBCI()) {
Klass catchType = null;
if (!toCheck.isCatchAll()) {
// exception handlers are similar to instanceof bytecodes, so we
// pass instanceof
catchType = resolveType(Bytecodes.INSTANCEOF, (char) toCheck.catchTypeCPI());
}
CompilerAsserts.partialEvaluationConstant(catchType);
if (catchType == null || InterpreterToVM.instanceOf(wrappedException.getGuestException(), catchType)) {
// the first found exception handler is our exception handler
handler = toCheck;
break;
}
}
}
if (handler != null) {
clearOperandStack(frame, top);
top = EspressoFrame.VALUES_START + getMethodVersion().getCodeAttribute().getMaxLocals();
checkNoForeignObjectAssumption(wrappedException.getGuestException());
putObject(frame, top, wrappedException.getGuestException());
top++;
int targetBCI = handler.getHandlerBCI();
nextStatementIndex = beforeJumpChecks(frame, curBCI, targetBCI, top, statementIndex, instrument, loopCount);
curBCI = targetBCI;
// skip bs.next()
continue loop;
} else {
if (instrument != null) {
instrument.notifyExceptionAt(frame, wrappedException, statementIndex);
}
if (CompilerDirectives.hasNextTier() && loopCount.value > 0) {
LoopNode.reportLoopCount(this, loopCount.value);
}
throw e;
}
}
} catch (EspressoOSRReturnException e) {
if (CompilerDirectives.hasNextTier() && loopCount.value > 0) {
LoopNode.reportLoopCount(this, loopCount.value);
}
return e.getResult();
}
assert curOpcode != WIDE && curOpcode != LOOKUPSWITCH && curOpcode != TABLESWITCH;
int targetBCI = curBCI + Bytecodes.lengthOf(curOpcode);
livenessAnalysis.performOnEdge(frame, curBCI, targetBCI);
if (instrument != null) {
nextStatementIndex = instrument.getNextStatementIndex(statementIndex, targetBCI);
}
top += Bytecodes.stackEffectOf(curOpcode);
curBCI = targetBCI;
}
}
use of com.oracle.truffle.api.exception.AbstractTruffleException in project graal by oracle.
the class InsightObjectTest method closeOfInsightHandleIsChecked.
@Test
public void closeOfInsightHandleIsChecked() throws Exception {
try (Context c = InsightObjectFactory.newContext()) {
AutoCloseable[] handle = { null };
Value agent = InsightObjectFactory.readInsight(c, null, handle);
InsightAPI agentAPI = agent.as(InsightAPI.class);
Assert.assertNotNull("Agent API obtained", agentAPI);
// @formatter:off
Source sampleScript = Source.newBuilder(InstrumentationTestLanguage.ID, "ROOT(\n" + " DEFINE(meaning,\n" + " EXPRESSION(\n" + " CONSTANT(6),\n" + " CONSTANT(7)\n" + " )\n" + " ),\n" + " CALL(meaning)\n" + ")", "sample.px").build();
// @formatter:on
final InsightAPI.OnEventHandler return42 = (ctx, frame) -> {
try {
ctx.returnValue(Collections.emptyMap());
} catch (RuntimeException ex) {
assertTrue("Expecting TruffleException: " + ex, ex instanceof AbstractTruffleException);
}
ctx.returnNow(42);
};
agentAPI.on("return", return42, createConfig(true, false, false, "meaning.*", null));
Value fourtyTwo = c.eval(sampleScript);
assertEquals(42, fourtyTwo.asInt());
handle[0].close();
Value sixSeven = c.eval(sampleScript);
assertEquals("Hook is no longer active", "(6+7)", sixSeven.asString());
try {
agentAPI.on("enter", return42, createConfig(true, false, false, "meaning.*", null));
fail("Expecting exception");
} catch (PolyglotException ex) {
assertEquals("insight: The script has already been closed", ex.getMessage());
}
}
}
use of com.oracle.truffle.api.exception.AbstractTruffleException in project graal by oracle.
the class NFINativeAccess method loadLibraryHelper.
@Pointer
protected TruffleObject loadLibraryHelper(String nfiSource) {
Source source = Source.newBuilder("nfi", nfiSource, "loadLibrary").build();
CallTarget target = env.parseInternal(source);
try {
return (TruffleObject) target.call();
} catch (IllegalArgumentException e) {
getLogger().log(Level.SEVERE, "TruffleNFI native library isolation is not supported", e);
throw EspressoError.shouldNotReachHere(e);
} catch (AbstractTruffleException e) {
// TODO(peterssen): Remove assert once GR-27045 reaches a definitive consensus.
assert isExpectedException(e);
// AbstractTruffleException is treated as if it were an UnsatisfiedLinkError.
getLogger().fine("AbstractTruffleException while loading library though NFI (" + nfiSource + ") : " + e.getMessage());
return null;
}
}
use of com.oracle.truffle.api.exception.AbstractTruffleException in project graal by oracle.
the class TruffleContextTest method testEvalInnerContextError.
@Test
public void testEvalInnerContextError() throws InteropException {
EvalContextTestException innerException = new EvalContextTestException();
EvalContextTestObject outerObject = new EvalContextTestObject();
setupLanguageThatReturns(() -> {
throw innerException;
});
TruffleContext innerContext = languageEnv.newContextBuilder().build();
innerException.expectedContext = innerContext;
outerObject.expectedContext = languageEnv.getContext();
try {
innerContext.evalInternal(null, newTruffleSource());
fail();
} catch (AbstractTruffleException e) {
// arguments of the parent context are entered in the outer context
Object result = InteropLibrary.getUncached().execute(e, outerObject);
// and return values are entered again in the inner context
result = InteropLibrary.getUncached().execute(result, outerObject);
try {
InteropLibrary.getUncached().throwException(result);
fail();
} catch (AbstractTruffleException innerEx) {
result = InteropLibrary.getUncached().execute(innerEx, outerObject);
}
}
assertEquals(3, innerException.executeCount);
assertEquals(3, outerObject.executeCount);
innerContext.close();
}
use of com.oracle.truffle.api.exception.AbstractTruffleException in project graal by oracle.
the class Target_com_oracle_truffle_espresso_polyglot_Polyglot method eval.
@Substitution
@JavaType(Object.class)
public static StaticObject eval(@JavaType(String.class) StaticObject language, @JavaType(String.class) StaticObject code, @Inject Meta meta) {
String languageId = meta.toHostString(language);
validateLanguage(languageId, meta);
Source source = getSource(languageId, meta.toHostString(code));
CallTarget callTarget;
try {
callTarget = meta.getContext().getEnv().parsePublic(source);
} catch (Exception e) {
throw rethrowExceptionAsEspresso(meta.java_lang_IllegalArgumentException, "Error when parsing the source: ", e);
}
Object evalResult;
try {
evalResult = callTarget.call();
} catch (Exception e) {
if (e instanceof AbstractTruffleException) {
throw rethrowExceptionAsEspresso(meta.java_lang_RuntimeException, "Exception during evaluation: ", e);
} else {
throw e;
}
}
if (evalResult instanceof StaticObject) {
return (StaticObject) evalResult;
}
return createForeignObject(evalResult, meta, InteropLibrary.getUncached());
}
Aggregations