use of com.oracle.truffle.espresso.runtime.EspressoException 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.espresso.runtime.EspressoException in project graal by oracle.
the class EspressoBindings method readMember.
@ExportMessage
Object readMember(String member, @CachedLibrary("this") InteropLibrary self, @Exclusive @Cached BranchProfile error) throws UnknownIdentifierException {
if (!isMemberReadable(member)) {
error.enter();
throw UnknownIdentifierException.create(member);
}
EspressoContext context = EspressoContext.get(self);
if (withNativeJavaVM && JAVA_VM.equals(member)) {
return context.getVM().getJavaVM();
}
Meta meta = context.getMeta();
try {
StaticObject clazz = (StaticObject) meta.java_lang_Class_forName_String_boolean_ClassLoader.invokeDirect(null, meta.toGuestString(member), false, loader);
return clazz.getMirrorKlass();
} catch (EspressoException e) {
error.enter();
if (InterpreterToVM.instanceOf(e.getGuestException(), meta.java_lang_ClassNotFoundException)) {
throw UnknownIdentifierException.create(member, e);
}
// exception during class loading
throw e;
}
}
use of com.oracle.truffle.espresso.runtime.EspressoException in project graal by oracle.
the class JniEnv method FindClass.
/**
* <h3>jclass FindClass(JNIEnv *env, const char *name);</h3>
*
* <p>
* FindClass locates the class loader associated with the current native method; that is, the
* class loader of the class that declared the native method. If the native method belongs to a
* system class, no class loader will be involved. Otherwise, the proper class loader will be
* invoked to load and link the named class. Since Java 2 SDK release 1.2, when FindClass is
* called through the Invocation Interface, there is no current native method or its associated
* class loader. In that case, the result of {@link ClassLoader#getSystemClassLoader} is used.
* This is the class loader the virtual machine creates for applications, and is able to locate
* classes listed in the java.class.path property. The name argument is a fully-qualified class
* name or an array type signature .
* <p>
* For example, the fully-qualified class name for the {@code java.lang.String} class is:
*
* <pre>
* "java/lang/String"}
* </pre>
*
* <p>
* The array type signature of the array class {@code java.lang.Object[]} is:
*
* <pre>
* "[Ljava/lang/Object;"
* </pre>
*
* @param namePtr a fully-qualified class name (that is, a package name, delimited by "/",
* followed by the class name). If the name begins with "[" (the array signature
* character), it returns an array class. The string is encoded in modified UTF-8.
* @return Returns a class object from a fully-qualified name, or NULL if the class cannot be
* found.
* @throws ClassFormatError if the class data does not specify a valid class.
* @throws ClassCircularityError if a class or interface would be its own superclass or
* superinterface.
* @throws NoClassDefFoundError if no definition for a requested class or interface can be
* found.
* @throws OutOfMemoryError if the system runs out of memory.
*/
@TruffleBoundary
@JniImpl
@JavaType(Class.class)
public StaticObject FindClass(@Pointer TruffleObject namePtr, @Inject SubstitutionProfiler profiler) {
String name = NativeUtils.interopPointerToString(namePtr);
Meta meta = getMeta();
if (name == null || (name.indexOf('.') > -1)) {
profiler.profile(7);
throw meta.throwExceptionWithMessage(meta.java_lang_NoClassDefFoundError, name);
}
String internalName = name;
if (!name.startsWith("[")) {
// Force 'L' type.
internalName = "L" + name + ";";
}
if (!Validation.validTypeDescriptor(ByteSequence.create(internalName), true)) {
profiler.profile(6);
throw meta.throwExceptionWithMessage(meta.java_lang_NoClassDefFoundError, name);
}
StaticObject protectionDomain = StaticObject.NULL;
StaticObject loader = StaticObject.NULL;
// security stack walk
StaticObject caller = getVM().JVM_GetCallerClass(0, profiler);
if (StaticObject.notNull(caller)) {
Klass callerKlass = caller.getMirrorKlass();
loader = callerKlass.getDefiningClassLoader();
if (StaticObject.isNull(loader) && Type.java_lang_ClassLoader$NativeLibrary.equals(callerKlass.getType())) {
StaticObject result = (StaticObject) getMeta().java_lang_ClassLoader$NativeLibrary_getFromClass.invokeDirect(null);
loader = result.getMirrorKlass().getDefiningClassLoader();
protectionDomain = getVM().JVM_GetProtectionDomain(result);
}
} else {
loader = (StaticObject) getMeta().java_lang_ClassLoader_getSystemClassLoader.invokeDirect(null);
}
StaticObject guestClass = StaticObject.NULL;
try {
String dotName = name.replace('/', '.');
guestClass = (StaticObject) getMeta().java_lang_Class_forName_String_boolean_ClassLoader.invokeDirect(null, meta.toGuestString(dotName), false, loader);
EspressoError.guarantee(StaticObject.notNull(guestClass), "Class.forName returned null");
} catch (EspressoException e) {
profiler.profile(5);
if (InterpreterToVM.instanceOf(e.getGuestException(), meta.java_lang_ClassNotFoundException)) {
profiler.profile(4);
throw meta.throwExceptionWithMessage(meta.java_lang_NoClassDefFoundError, name);
}
throw e;
}
meta.HIDDEN_PROTECTION_DOMAIN.setHiddenObject(guestClass, protectionDomain);
// FindClass should initialize the class.
guestClass.getMirrorKlass().safeInitialize();
return guestClass;
}
use of com.oracle.truffle.espresso.runtime.EspressoException in project graal by oracle.
the class JniEnv method ExceptionDescribe.
/**
* <h3>void ExceptionDescribe(JNIEnv *env);</h3>
* <p>
* Prints an exception and a backtrace of the stack to a system error-reporting channel, such as
* stderr. This is a convenience routine provided for debugging.
*/
@JniImpl
public void ExceptionDescribe() {
EspressoException ex = getPendingEspressoException();
if (ex != null) {
StaticObject guestException = ex.getGuestException();
assert InterpreterToVM.instanceOf(guestException, getMeta().java_lang_Throwable);
// Dynamic lookup.
Method printStackTrace = guestException.getKlass().lookupMethod(Name.printStackTrace, Signature._void);
printStackTrace.invokeDirect(guestException);
// Restore exception cleared by invokeDirect.
setPendingException(ex);
}
}
use of com.oracle.truffle.espresso.runtime.EspressoException in project graal by oracle.
the class ObjectKlass method getNestMembers.
@Override
public Klass[] getNestMembers() {
if (this != nest()) {
return nest().getNestMembers();
}
NestMembersAttribute nestMembers = (NestMembersAttribute) getAttribute(NestMembersAttribute.NAME);
if (nestMembers == null || nestMembers.getClasses().length == 0) {
return new Klass[] { nest() };
}
RuntimeConstantPool pool = getConstantPool();
ArrayList<Klass> klasses = new ArrayList<>(1 + nestMembers.getClasses().length);
klasses.add(nest());
for (int i = 0; i < nestMembers.getClasses().length; i++) {
int index = nestMembers.getClasses()[i];
try {
klasses.add(pool.resolvedKlassAt(this, index));
} catch (EspressoException e) {
/*
* Don't allow badly constructed nest members to break execution here, only report
* well-constructed entries.
*/
}
}
return klasses.toArray(Klass.EMPTY_ARRAY);
}
Aggregations