Search in sources :

Example 1 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class BytecodeNode method dispatchQuickened.

// endregion quickenForeign
private BaseQuickNode dispatchQuickened(int top, int curBCI, char cpi, int opcode, int statementIndex, Method resolutionSeed, boolean allowFieldAccessInlining) {
    assert !allowFieldAccessInlining || getContext().InlineFieldAccessors;
    BaseQuickNode invoke;
    Method resolved = resolutionSeed;
    switch(opcode) {
        case INVOKESTATIC:
            // instruction throws an IncompatibleClassChangeError.
            if (!resolved.isStatic()) {
                CompilerDirectives.transferToInterpreter();
                Meta meta = getMeta();
                throw meta.throwException(meta.java_lang_IncompatibleClassChangeError);
            }
            break;
        case INVOKEINTERFACE:
            // invokeinterface instruction throws an IncompatibleClassChangeError.
            if (resolved.isStatic() || (getContext().getJavaVersion().java8OrEarlier() && resolved.isPrivate())) {
                CompilerDirectives.transferToInterpreter();
                Meta meta = getMeta();
                throw meta.throwException(meta.java_lang_IncompatibleClassChangeError);
            }
            break;
        case INVOKEVIRTUAL:
            // instruction throws an IncompatibleClassChangeError.
            if (resolved.isStatic()) {
                CompilerDirectives.transferToInterpreter();
                Meta meta = getMeta();
                throw meta.throwException(meta.java_lang_IncompatibleClassChangeError);
            }
            break;
        case INVOKESPECIAL:
            // instruction, a NoSuchMethodError is thrown.
            if (resolved.isConstructor()) {
                if (resolved.getDeclaringKlass().getName() != getConstantPool().methodAt(cpi).getHolderKlassName(getConstantPool())) {
                    CompilerDirectives.transferToInterpreter();
                    Meta meta = getMeta();
                    throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchMethodError, meta.toGuestString(resolved.getDeclaringKlass().getNameAsString() + "." + resolved.getName() + resolved.getRawSignature()));
                }
            }
            // instruction throws an IncompatibleClassChangeError.
            if (resolved.isStatic()) {
                CompilerDirectives.transferToInterpreter();
                Meta meta = getMeta();
                throw meta.throwException(meta.java_lang_IncompatibleClassChangeError);
            }
            // version of the class file.
            if (!resolved.isConstructor()) {
                Klass declaringKlass = getMethod().getDeclaringKlass();
                Klass symbolicRef = ((MethodRefConstant.Indexes) getConstantPool().methodAt(cpi)).getResolvedHolderKlass(declaringKlass, getConstantPool());
                if (!symbolicRef.isInterface() && symbolicRef != declaringKlass && declaringKlass.getSuperKlass() != null && symbolicRef != declaringKlass.getSuperKlass() && symbolicRef.isAssignableFrom(declaringKlass)) {
                    resolved = declaringKlass.getSuperKlass().lookupMethod(resolved.getName(), resolved.getRawSignature(), declaringKlass);
                }
            }
            break;
        default:
            CompilerDirectives.transferToInterpreter();
            throw EspressoError.unimplemented("Quickening for " + Bytecodes.nameOf(opcode));
    }
    if (allowFieldAccessInlining && resolved.isInlinableGetter()) {
        invoke = InlinedGetterNode.create(resolved, top, opcode, curBCI, statementIndex);
    } else if (allowFieldAccessInlining && resolved.isInlinableSetter()) {
        invoke = InlinedSetterNode.create(resolved, top, opcode, curBCI, statementIndex);
    } else if (resolved.isPolySignatureIntrinsic()) {
        invoke = new InvokeHandleNode(resolved, getDeclaringKlass(), top, curBCI);
    } else if (opcode == INVOKEINTERFACE && resolved.getITableIndex() < 0) {
        if (resolved.isPrivate()) {
            assert getJavaVersion().java9OrLater();
            // Interface private methods do not appear in itables.
            invoke = new InvokeSpecialQuickNode(resolved, top, curBCI);
        } else {
            // Can happen in old classfiles that calls j.l.Object on interfaces.
            invoke = new InvokeVirtualQuickNode(resolved, top, curBCI);
        }
    } else if (opcode == INVOKEVIRTUAL && (resolved.isFinalFlagSet() || resolved.getDeclaringKlass().isFinalFlagSet() || resolved.isPrivate())) {
        invoke = new InvokeSpecialQuickNode(resolved, top, curBCI);
    } else {
        // @formatter:off
        switch(opcode) {
            case INVOKESTATIC:
                invoke = new InvokeStaticQuickNode(resolved, top, curBCI);
                break;
            case INVOKEINTERFACE:
                invoke = new InvokeInterfaceQuickNode(resolved, top, curBCI);
                break;
            case INVOKEVIRTUAL:
                invoke = new InvokeVirtualQuickNode(resolved, top, curBCI);
                break;
            case INVOKESPECIAL:
                invoke = new InvokeSpecialQuickNode(resolved, top, curBCI);
                break;
            default:
                CompilerDirectives.transferToInterpreter();
                throw EspressoError.unimplemented("Quickening for " + Bytecodes.nameOf(opcode));
        }
    // @formatter:on
    }
    return invoke;
}
Also used : Meta(com.oracle.truffle.espresso.meta.Meta) Klass(com.oracle.truffle.espresso.impl.Klass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) InvokeStaticQuickNode(com.oracle.truffle.espresso.nodes.quick.invoke.InvokeStaticQuickNode) InvokeHandleNode(com.oracle.truffle.espresso.nodes.quick.invoke.InvokeHandleNode) BaseQuickNode(com.oracle.truffle.espresso.nodes.quick.BaseQuickNode) Method(com.oracle.truffle.espresso.impl.Method) InvokeVirtualQuickNode(com.oracle.truffle.espresso.nodes.quick.invoke.InvokeVirtualQuickNode) InvokeSpecialQuickNode(com.oracle.truffle.espresso.nodes.quick.invoke.InvokeSpecialQuickNode) InvokeInterfaceQuickNode(com.oracle.truffle.espresso.nodes.quick.invoke.InvokeInterfaceQuickNode)

Example 2 with Klass

use of com.oracle.truffle.espresso.impl.Klass 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;
    }
}
Also used : AbstractTruffleException(com.oracle.truffle.api.exception.AbstractTruffleException) TruffleSafepoint(com.oracle.truffle.api.TruffleSafepoint) ExceptionHandler(com.oracle.truffle.espresso.meta.ExceptionHandler) DebugCounter(com.oracle.truffle.espresso.perf.DebugCounter) EspressoException(com.oracle.truffle.espresso.runtime.EspressoException) Klass(com.oracle.truffle.espresso.impl.Klass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) EspressoExitException(com.oracle.truffle.espresso.runtime.EspressoExitException) BytecodeTableSwitch(com.oracle.truffle.espresso.bytecode.BytecodeTableSwitch) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) BaseQuickNode(com.oracle.truffle.espresso.nodes.quick.BaseQuickNode) BytecodeLookupSwitch(com.oracle.truffle.espresso.bytecode.BytecodeLookupSwitch) ExplodeLoop(com.oracle.truffle.api.nodes.ExplodeLoop)

Example 3 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class Meta method resolveSymbolOrNull.

/**
 * Resolves an internal symbolic type descriptor taken from the constant pool, and returns the
 * corresponding Klass.
 * <li>If the symbol represents an internal primitive (/ex: 'B' or 'I'), this method returns the
 * corresponding primitive. Primitives are therefore not "loaded", but directly resolved..
 * <li>If the symbol is a symbolic references, it asks the given ClassLoader to load the
 * corresponding Klass.
 * <li>If the symbol represents an array, resolves its elemental type, and returns the array
 * corresponding array Klass.
 *
 * @return The asked Klass, or null if no representation can be found.
 */
public Klass resolveSymbolOrNull(Symbol<Type> type, @JavaType(ClassLoader.class) StaticObject classLoader, StaticObject protectionDomain) {
    CompilerAsserts.partialEvaluationConstant(type);
    assert classLoader != null : "use StaticObject.NULL for BCL";
    // Resolution only resolves references. Bypass loading for primitives.
    Klass k = resolvePrimitive(type);
    if (k != null) {
        return k;
    }
    if (Types.isArray(type)) {
        Klass elemental = resolveSymbolOrNull(getTypes().getElementalType(type), classLoader, protectionDomain);
        if (elemental == null) {
            return null;
        }
        return elemental.getArrayClass(Types.getArrayDimensions(type));
    }
    return loadKlassOrNull(type, classLoader, protectionDomain);
}
Also used : Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) PrimitiveKlass(com.oracle.truffle.espresso.impl.PrimitiveKlass)

Example 4 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class MHInvokeGenericNode method create.

public static MHInvokeGenericNode create(Klass accessingKlass, Method method, Symbol<Symbol.Name> methodName, Symbol<Symbol.Signature> signature, Meta meta) {
    Klass callerKlass = accessingKlass == null ? meta.java_lang_Object : accessingKlass;
    StaticObject appendixBox = StaticObject.createArray(meta.java_lang_Object_array, new StaticObject[1]);
    // Ask java code to spin an invoker for us.
    StaticObject memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkMethod.invokeDirect(null, callerKlass.mirror(), (int) REF_invokeVirtual, method.getDeclaringKlass().mirror(), meta.toGuestString(methodName), meta.toGuestString(signature), appendixBox);
    StaticObject appendix = appendixBox.get(0);
    return new MHInvokeGenericNode(method, memberName, appendix);
}
Also used : Klass(com.oracle.truffle.espresso.impl.Klass) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject)

Example 5 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class JniEnv method GetMethodID.

/**
 * <h3>jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);</h3>
 * <p>
 * Returns the method ID for an instance (nonstatic) method of a class or interface. The method
 * may be defined in one of the clazz’s superclasses and inherited by clazz. The method is
 * determined by its name and signature.
 * <p>
 * GetMethodID() causes an uninitialized class to be initialized.
 * <p>
 * To obtain the method ID of a constructor, supply <init> as the method name and void (V) as
 * the return type.
 *
 * @param clazz a Java class object.
 * @param namePtr the method name in a 0-terminated modified UTF-8 string.
 * @param signaturePtr the method signature in 0-terminated modified UTF-8 string.
 * @return a method ID, or NULL if the specified method cannot be found.
 * @throws NoSuchMethodError if the specified method cannot be found.
 * @throws ExceptionInInitializerError if the class initializer fails due to an exception.
 * @throws OutOfMemoryError if the system runs out of memory.
 */
@JniImpl
@Handle(Method.class)
public long GetMethodID(@JavaType(Class.class) StaticObject clazz, @Pointer TruffleObject namePtr, @Pointer TruffleObject signaturePtr) {
    String name = NativeUtils.interopPointerToString(namePtr);
    String signature = NativeUtils.interopPointerToString(signaturePtr);
    assert name != null && signature != null;
    Method method = null;
    Symbol<Name> methodName = getNames().lookup(name);
    if (methodName != null) {
        Symbol<Signature> methodSignature = getSignatures().lookupValidSignature(signature);
        if (methodSignature != null) {
            Klass klass = clazz.getMirrorKlass();
            klass.safeInitialize();
            // Lookup only if name and type are known symbols.
            method = klass.lookupMethod(methodName, methodSignature, klass);
        }
    }
    if (method == null || method.isStatic()) {
        Meta meta = getMeta();
        throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchMethodError, name);
    }
    return methodIds.handlify(method);
}
Also used : Meta(com.oracle.truffle.espresso.meta.Meta) Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) NativeSignature(com.oracle.truffle.espresso.ffi.NativeSignature) Signature(com.oracle.truffle.espresso.descriptors.Symbol.Signature) Method(com.oracle.truffle.espresso.impl.Method) Name(com.oracle.truffle.espresso.descriptors.Symbol.Name)

Aggregations

Klass (com.oracle.truffle.espresso.impl.Klass)71 ObjectKlass (com.oracle.truffle.espresso.impl.ObjectKlass)54 ArrayKlass (com.oracle.truffle.espresso.impl.ArrayKlass)49 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)33 JavaType (com.oracle.truffle.espresso.substitutions.JavaType)24 Meta (com.oracle.truffle.espresso.meta.Meta)21 Method (com.oracle.truffle.espresso.impl.Method)19 TruffleBoundary (com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)10 Name (com.oracle.truffle.espresso.descriptors.Symbol.Name)10 NoSafepoint (com.oracle.truffle.espresso.jni.NoSafepoint)10 ExportMessage (com.oracle.truffle.api.library.ExportMessage)8 Field (com.oracle.truffle.espresso.impl.Field)7 ArrayList (java.util.ArrayList)7 RuntimeConstantPool (com.oracle.truffle.espresso.classfile.RuntimeConstantPool)6 EspressoException (com.oracle.truffle.espresso.runtime.EspressoException)6 InnerClassesAttribute (com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute)5 Type (com.oracle.truffle.espresso.descriptors.Symbol.Type)5 NativeType (com.oracle.truffle.espresso.ffi.NativeType)5 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)3 EnclosingMethodAttribute (com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute)3