Search in sources :

Example 1 with Meta

use of com.oracle.truffle.espresso.meta.Meta 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 Meta

use of com.oracle.truffle.espresso.meta.Meta in project graal by oracle.

the class BytecodeNode method getField.

/**
 * Returns the stack effect (slot delta) that cannot be inferred solely from the bytecode. e.g.
 * PUTFIELD always pops the receiver, but the result size (1 or 2) is unknown.
 *
 * <pre>
 *   top += getField(frame, top, resolveField(...)); break; // stack effect that depends on the field
 *   top += Bytecodes.stackEffectOf(curOpcode); // stack effect that depends solely on GETFIELD.
 *   // at this point `top` must have the correct value.
 *   curBCI = bs.next(curBCI);
 * </pre>
 */
private int getField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex) {
    assert opcode == GETFIELD || opcode == GETSTATIC;
    CompilerAsserts.partialEvaluationConstant(field);
    /*
         * GETFIELD: Otherwise, if the resolved field is a static field, getfield throws an
         * IncompatibleClassChangeError.
         *
         * GETSTATIC: Otherwise, if the resolved field is not a static (class) field or an interface
         * field, getstatic throws an IncompatibleClassChangeError.
         */
    if (field.isStatic() != (opcode == GETSTATIC)) {
        CompilerDirectives.transferToInterpreter();
        Meta meta = getMeta();
        throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, String.format("Expected %s field %s.%s", (opcode == GETSTATIC) ? "static" : "non-static", field.getDeclaringKlass().getNameAsString(), field.getNameAsString()));
    }
    assert field.isStatic() == (opcode == GETSTATIC);
    int slot = top - 1;
    StaticObject receiver = field.isStatic() ? field.getDeclaringKlass().tryInitializeAndGetStatics() : // Do not release the object, it might be read again in GetFieldNode
    nullCheck(peekObject(frame, slot));
    if (!noForeignObjects.isValid() && opcode == GETFIELD) {
        if (receiver.isForeignObject()) {
            // Restore the receiver for quickening.
            putObject(frame, slot, receiver);
            return quickenGetField(frame, top, curBCI, opcode, statementIndex, field);
        }
    }
    if (instrumentation != null) {
        instrumentation.notifyFieldAccess(frame, statementIndex, field, receiver);
    }
    int resultAt = field.isStatic() ? top : (top - 1);
    // @formatter:off
    switch(field.getKind()) {
        case Boolean:
            putInt(frame, resultAt, InterpreterToVM.getFieldBoolean(receiver, field) ? 1 : 0);
            break;
        case Byte:
            putInt(frame, resultAt, InterpreterToVM.getFieldByte(receiver, field));
            break;
        case Char:
            putInt(frame, resultAt, InterpreterToVM.getFieldChar(receiver, field));
            break;
        case Short:
            putInt(frame, resultAt, InterpreterToVM.getFieldShort(receiver, field));
            break;
        case Int:
            putInt(frame, resultAt, InterpreterToVM.getFieldInt(receiver, field));
            break;
        case Double:
            putDouble(frame, resultAt, InterpreterToVM.getFieldDouble(receiver, field));
            break;
        case Float:
            putFloat(frame, resultAt, InterpreterToVM.getFieldFloat(receiver, field));
            break;
        case Long:
            putLong(frame, resultAt, InterpreterToVM.getFieldLong(receiver, field));
            break;
        case Object:
            {
                StaticObject value = InterpreterToVM.getFieldObject(receiver, field);
                putObject(frame, resultAt, value);
                checkNoForeignObjectAssumption(value);
                break;
            }
        default:
            CompilerDirectives.transferToInterpreter();
            throw EspressoError.shouldNotReachHere("unexpected kind");
    }
    // @formatter:on
    return field.getKind().getSlotCount();
}
Also used : Meta(com.oracle.truffle.espresso.meta.Meta) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) TruffleSafepoint(com.oracle.truffle.api.TruffleSafepoint)

Example 3 with Meta

use of com.oracle.truffle.espresso.meta.Meta in project graal by oracle.

the class BytecodeNode method checkNonZero.

private long checkNonZero(long value) {
    if (value != 0L) {
        return value;
    }
    enterImplicitExceptionProfile();
    Meta meta = getMeta();
    throw meta.throwExceptionWithMessage(meta.java_lang_ArithmeticException, "/ by zero");
}
Also used : Meta(com.oracle.truffle.espresso.meta.Meta)

Example 4 with Meta

use of com.oracle.truffle.espresso.meta.Meta in project graal by oracle.

the class BytecodeNode method checkNonZero.

private int checkNonZero(int value) {
    if (value != 0) {
        return value;
    }
    enterImplicitExceptionProfile();
    Meta meta = getMeta();
    throw meta.throwExceptionWithMessage(meta.java_lang_ArithmeticException, "/ by zero");
}
Also used : Meta(com.oracle.truffle.espresso.meta.Meta)

Example 5 with Meta

use of com.oracle.truffle.espresso.meta.Meta in project graal by oracle.

the class InvokeInterface method methodLookup.

static Method.MethodVersion methodLookup(Method resolutionSeed, Klass receiverKlass) {
    assert !receiverKlass.isArray();
    if (resolutionSeed.isRemovedByRedefition()) {
        /*
             * Accept a slow path once the method has been removed put method behind a boundary to
             * avoid a deopt loop
             */
        return resolutionSeed.getContext().getClassRedefinition().handleRemovedMethod(resolutionSeed, receiverKlass).getMethodVersion();
    }
    int iTableIndex = resolutionSeed.getITableIndex();
    Method method = ((ObjectKlass) receiverKlass).itableLookup(resolutionSeed.getDeclaringKlass(), iTableIndex);
    if (!method.isPublic()) {
        transferToInterpreterAndInvalidate();
        Meta meta = receiverKlass.getMeta();
        throw meta.throwException(meta.java_lang_IllegalAccessError);
    }
    return method.getMethodVersion();
}
Also used : Meta(com.oracle.truffle.espresso.meta.Meta) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) Method(com.oracle.truffle.espresso.impl.Method)

Aggregations

Meta (com.oracle.truffle.espresso.meta.Meta)82 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)29 Method (com.oracle.truffle.espresso.impl.Method)27 ExportMessage (com.oracle.truffle.api.library.ExportMessage)24 Klass (com.oracle.truffle.espresso.impl.Klass)21 ObjectKlass (com.oracle.truffle.espresso.impl.ObjectKlass)21 JavaType (com.oracle.truffle.espresso.substitutions.JavaType)21 ArrayKlass (com.oracle.truffle.espresso.impl.ArrayKlass)20 TruffleBoundary (com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)17 ArityException (com.oracle.truffle.api.interop.ArityException)9 UnsupportedTypeException (com.oracle.truffle.api.interop.UnsupportedTypeException)9 NoSafepoint (com.oracle.truffle.espresso.jni.NoSafepoint)9 Name (com.oracle.truffle.espresso.descriptors.Symbol.Name)8 Type (com.oracle.truffle.espresso.descriptors.Symbol.Type)6 NativeType (com.oracle.truffle.espresso.ffi.NativeType)4 Field (com.oracle.truffle.espresso.impl.Field)4 ArrayList (java.util.ArrayList)4 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)3 UnsupportedMessageException (com.oracle.truffle.api.interop.UnsupportedMessageException)3 RuntimeConstantPool (com.oracle.truffle.espresso.classfile.RuntimeConstantPool)3