Search in sources :

Example 26 with JavaType

use of jdk.vm.ci.meta.JavaType in project graal by oracle.

the class ClassfileBytecode method getExceptionHandlers.

@Override
public ExceptionHandler[] getExceptionHandlers() {
    if (exceptionTableBytes == null) {
        return new ExceptionHandler[0];
    }
    final int exceptionTableLength = exceptionTableBytes.length / EXCEPTION_HANDLER_TABLE_SIZE_IN_BYTES;
    ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength];
    DataInputStream stream = new DataInputStream(new ByteArrayInputStream(exceptionTableBytes));
    for (int i = 0; i < exceptionTableLength; i++) {
        try {
            final int startPc = stream.readUnsignedShort();
            final int endPc = stream.readUnsignedShort();
            final int handlerPc = stream.readUnsignedShort();
            int catchTypeIndex = stream.readUnsignedShort();
            JavaType catchType;
            if (catchTypeIndex == 0) {
                catchType = null;
            } else {
                // opcode is not used
                final int opcode = -1;
                catchType = constantPool.lookupType(catchTypeIndex, opcode);
                // Check for Throwable which catches everything.
                if (catchType.toJavaName().equals("java.lang.Throwable")) {
                    catchTypeIndex = 0;
                    catchType = null;
                }
            }
            handlers[i] = new ExceptionHandler(startPc, endPc, handlerPc, catchTypeIndex, catchType);
        } catch (IOException e) {
            throw new GraalError(e);
        }
    }
    return handlers;
}
Also used : ExceptionHandler(jdk.vm.ci.meta.ExceptionHandler) JavaType(jdk.vm.ci.meta.JavaType) GraalError(org.graalvm.compiler.debug.GraalError) ByteArrayInputStream(java.io.ByteArrayInputStream) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream)

Example 27 with JavaType

use of jdk.vm.ci.meta.JavaType in project graal by oracle.

the class MethodHandleNode method getTargetInvokeNode.

/**
 * Helper function to get the {@link InvokeNode} for the targetMethod of a
 * java.lang.invoke.MemberName.
 *
 * @param adder
 * @param target the target, already loaded from the member name node
 *
 * @return invoke node for the member name target
 */
private static InvokeNode getTargetInvokeNode(GraphAdder adder, IntrinsicMethod intrinsicMethod, int bci, StampPair returnStamp, ValueNode[] originalArguments, ResolvedJavaMethod target, ResolvedJavaMethod original) {
    if (target == null) {
        return null;
    }
    // In lambda forms we erase signature types to avoid resolving issues
    // involving class loaders. When we optimize a method handle invoke
    // to a direct call we must cast the receiver and arguments to its
    // actual types.
    Signature signature = target.getSignature();
    final boolean isStatic = target.isStatic();
    final int receiverSkip = isStatic ? 0 : 1;
    Assumptions assumptions = adder.getAssumptions();
    ResolvedJavaMethod realTarget = null;
    if (target.canBeStaticallyBound()) {
        realTarget = target;
    } else {
        ResolvedJavaType targetType = target.getDeclaringClass();
        // Try to bind based on the declaredType
        AssumptionResult<ResolvedJavaMethod> concreteMethod = targetType.findUniqueConcreteMethod(target);
        if (concreteMethod == null) {
            // Try to get the most accurate receiver type
            if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) {
                ValueNode receiver = getReceiver(originalArguments);
                TypeReference receiverType = StampTool.typeReferenceOrNull(receiver.stamp(NodeView.DEFAULT));
                if (receiverType != null) {
                    concreteMethod = receiverType.getType().findUniqueConcreteMethod(target);
                }
            }
        }
        if (concreteMethod != null && concreteMethod.canRecordTo(assumptions)) {
            concreteMethod.recordTo(assumptions);
            realTarget = concreteMethod.getResult();
        }
    }
    if (realTarget != null) {
        // Don't mutate the passed in arguments
        ValueNode[] arguments = originalArguments.clone();
        // Cast receiver to its type.
        if (!isStatic) {
            JavaType receiverType = target.getDeclaringClass();
            maybeCastArgument(adder, arguments, 0, receiverType);
        }
        // Cast reference arguments to its type.
        for (int index = 0; index < signature.getParameterCount(false); index++) {
            JavaType parameterType = signature.getParameterType(index, target.getDeclaringClass());
            maybeCastArgument(adder, arguments, receiverSkip + index, parameterType);
        }
        InvokeNode invoke = createTargetInvokeNode(assumptions, intrinsicMethod, realTarget, original, bci, returnStamp, arguments);
        assert invoke != null : "graph has been modified so this must result an invoke";
        return invoke;
    }
    return null;
}
Also used : ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) Signature(jdk.vm.ci.meta.Signature) Assumptions(jdk.vm.ci.meta.Assumptions) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 28 with JavaType

use of jdk.vm.ci.meta.JavaType in project graal by oracle.

the class CEntryPointCallStubMethod method generateExceptionHandler.

private void generateExceptionHandler(HostedProviders providers, SubstrateGraphKit kit, ExceptionObjectNode exception, JavaKind returnKind) {
    if (entryPointData.getExceptionHandler() == CEntryPointOptions.FatalExceptionHandler.class) {
        kit.append(new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, exception));
        kit.append(new DeadEndNode());
    } else {
        ResolvedJavaType throwable = providers.getMetaAccess().lookupJavaType(Throwable.class);
        ResolvedJavaType handler = providers.getMetaAccess().lookupJavaType(entryPointData.getExceptionHandler());
        ResolvedJavaMethod[] handlerMethods = handler.getDeclaredMethods();
        UserError.guarantee(handlerMethods.length == 1 && handlerMethods[0].isStatic(), "Exception handler class must declare exactly one static method: " + targetMethod.format("%H.%n(%p)") + " -> " + handler.toJavaName());
        JavaType[] handlerParameterTypes = handlerMethods[0].toParameterTypes();
        UserError.guarantee(handlerParameterTypes.length == 1 && ((ResolvedJavaType) handlerParameterTypes[0]).isAssignableFrom(throwable), "Exception handler method must have exactly one parameter of type Throwable: " + targetMethod.format("%H.%n(%p)") + " -> " + handlerMethods[0].format("%H.%n(%p)"));
        int handlerExceptionBci = kit.bci();
        InvokeWithExceptionNode handlerInvoke = kit.startInvokeWithException(handlerMethods[0], InvokeKind.Static, kit.getFrameState(), kit.bci(), handlerExceptionBci, exception);
        kit.noExceptionPart();
        ValueNode returnValue = handlerInvoke;
        if (handlerInvoke.getStackKind() != returnKind) {
            JavaKind fromKind = handlerInvoke.getStackKind();
            if (fromKind == JavaKind.Float && returnKind == JavaKind.Double) {
                returnValue = kit.unique(new FloatConvertNode(FloatConvert.F2D, returnValue));
            } else if (fromKind.isUnsigned() && returnKind.isNumericInteger() && returnKind.getBitCount() > fromKind.getBitCount()) {
                returnValue = kit.unique(new ZeroExtendNode(returnValue, returnKind.getBitCount()));
            } else if (fromKind.isNumericInteger() && returnKind.isNumericInteger() && returnKind.getBitCount() > fromKind.getBitCount()) {
                returnValue = kit.unique(new SignExtendNode(returnValue, returnKind.getBitCount()));
            } else {
                throw UserError.abort("Exception handler method return type must be assignable to entry point method return type: " + targetMethod.format("%H.%n(%p)") + " -> " + handlerMethods[0].format("%H.%n(%p)"));
            }
        }
        kit.createReturn(returnValue, returnValue.getStackKind());
        // fail-safe for exceptions in exception handler
        kit.exceptionPart();
        kit.append(new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, kit.exceptionObject()));
        kit.append(new DeadEndNode());
        kit.endInvokeWithException();
    }
}
Also used : CEntryPointOptions(com.oracle.svm.core.c.function.CEntryPointOptions) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) CEntryPointLeaveNode(com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) FloatConvertNode(org.graalvm.compiler.nodes.calc.FloatConvertNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) DeadEndNode(com.oracle.svm.core.graal.nodes.DeadEndNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 29 with JavaType

use of jdk.vm.ci.meta.JavaType in project graal by oracle.

the class CEntryPointCallStubMethod method adaptReturnValue.

private ValueNode adaptReturnValue(ResolvedJavaMethod method, HostedProviders providers, Purpose purpose, UniverseMetaAccess metaAccess, NativeLibraries nativeLibraries, HostedGraphKit kit, ValueNode invokeValue) {
    ValueNode returnValue = invokeValue;
    if (returnValue.getStackKind().isPrimitive()) {
        return returnValue;
    }
    JavaType returnType = method.getSignature().getReturnType(null);
    ElementInfo typeInfo = nativeLibraries.findElementInfo(returnType);
    if (typeInfo instanceof EnumInfo) {
        UserError.guarantee(typeInfo.getChildren().stream().anyMatch(EnumValueInfo.class::isInstance), "Enum class " + returnType.toJavaName() + " needs a method that is annotated with @" + CEnumValue.class + " because it is used as the return type of an entry point method: " + targetMethod.format("%H.%n(%p)"));
        IsNullNode isNull = kit.unique(new IsNullNode(returnValue));
        kit.startIf(isNull, BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY);
        kit.thenPart();
        ResolvedJavaType enumExceptionType = metaAccess.lookupJavaType(RuntimeException.class);
        NewInstanceNode enumException = kit.append(new NewInstanceNode(enumExceptionType, true));
        Iterator<ResolvedJavaMethod> enumExceptionCtor = Arrays.stream(enumExceptionType.getDeclaredConstructors()).filter(c -> c.getSignature().getParameterCount(false) == 1 && c.getSignature().getParameterType(0, null).equals(metaAccess.lookupJavaType(String.class))).iterator();
        ConstantNode enumExceptionMessage = kit.createConstant(kit.getConstantReflection().forString("null return value cannot be converted to a C enum value"), JavaKind.Object);
        kit.createJavaCallWithExceptionAndUnwind(InvokeKind.Special, enumExceptionCtor.next(), enumException, enumExceptionMessage);
        assert !enumExceptionCtor.hasNext();
        kit.append(new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, enumException));
        kit.append(new DeadEndNode());
        kit.endIf();
        // Always return enum values as a signed word because it should never be a problem if
        // the caller expects a narrower integer type and the various checks already handle
        // replacements with word types
        CInterfaceEnumTool tool = new CInterfaceEnumTool(providers.getMetaAccess(), providers.getSnippetReflection());
        JavaKind cEnumReturnType = providers.getWordTypes().getWordKind();
        assert !cEnumReturnType.isUnsigned() : "requires correct representation of signed values";
        returnValue = tool.createEnumValueInvoke(kit, (EnumInfo) typeInfo, cEnumReturnType, returnValue);
    } else if (purpose != Purpose.ANALYSIS) {
        // for analysis test cases: abort only during compilation
        throw UserError.abort("Entry point method return types are restricted to primitive types, word types and enumerations (@" + CEnum.class.getSimpleName() + "): " + targetMethod.format("%H.%n(%p)"));
    }
    return returnValue;
}
Also used : Isolate(org.graalvm.nativeimage.Isolate) HostedProviders(com.oracle.graal.pointsto.meta.HostedProviders) Arrays(java.util.Arrays) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) GraphProvider(com.oracle.graal.pointsto.infrastructure.GraphProvider) NativeBootImage(com.oracle.svm.hosted.image.NativeBootImage) Constant(jdk.vm.ci.meta.Constant) CEntryPointOptions(com.oracle.svm.core.c.function.CEntryPointOptions) NarrowNode(org.graalvm.compiler.nodes.calc.NarrowNode) CInterfaceEnumTool(com.oracle.svm.hosted.phases.CInterfaceEnumTool) StampFactory(org.graalvm.compiler.core.common.type.StampFactory) NativeLibraries(com.oracle.svm.hosted.c.NativeLibraries) JavaKind(jdk.vm.ci.meta.JavaKind) IsolateThread(org.graalvm.nativeimage.IsolateThread) UserError(com.oracle.svm.core.util.UserError) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) FloatConvertNode(org.graalvm.compiler.nodes.calc.FloatConvertNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) EnumInfo(com.oracle.svm.hosted.c.info.EnumInfo) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) CEntryPointPrologueBailoutNode(com.oracle.svm.core.graal.nodes.CEntryPointPrologueBailoutNode) CEntryPointSetup(com.oracle.svm.core.c.function.CEntryPointSetup) CEntryPointLeaveNode(com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode) ElementInfo(com.oracle.svm.hosted.c.info.ElementInfo) ConstantPool(jdk.vm.ci.meta.ConstantPool) CEnumValue(org.graalvm.nativeimage.c.constant.CEnumValue) UniverseMetaAccess(com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess) Uninterruptible(com.oracle.svm.core.annotate.Uninterruptible) VMError(com.oracle.svm.core.util.VMError) ValueNode(org.graalvm.compiler.nodes.ValueNode) JavaType(jdk.vm.ci.meta.JavaType) FrameState(org.graalvm.compiler.nodes.FrameState) Type(java.lang.reflect.Type) NodeIterable(org.graalvm.compiler.graph.iterators.NodeIterable) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) Modifier(java.lang.reflect.Modifier) Annotation(java.lang.annotation.Annotation) NoPrologue(com.oracle.svm.core.c.function.CEntryPointOptions.NoPrologue) NoEpilogue(com.oracle.svm.core.c.function.CEntryPointOptions.NoEpilogue) SpeculationLog(jdk.vm.ci.meta.SpeculationLog) CEnum(org.graalvm.nativeimage.c.constant.CEnum) HostedGraphKit(com.oracle.svm.hosted.phases.HostedGraphKit) MetaAccessProvider(jdk.vm.ci.meta.MetaAccessProvider) Signature(jdk.vm.ci.meta.Signature) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) WrappedJavaMethod(com.oracle.graal.pointsto.infrastructure.WrappedJavaMethod) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) InvokeKind(org.graalvm.compiler.nodes.CallTargetNode.InvokeKind) EnumValueInfo(com.oracle.svm.hosted.c.info.EnumValueInfo) DebugContext(org.graalvm.compiler.debug.DebugContext) CEntryPointCallStubs(com.oracle.svm.core.code.CEntryPointCallStubs) EnumLookupInfo(com.oracle.svm.hosted.c.info.EnumLookupInfo) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) AnalysisMetaAccess(com.oracle.graal.pointsto.meta.AnalysisMetaAccess) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) AnalysisMethod(com.oracle.graal.pointsto.meta.AnalysisMethod) Iterator(java.util.Iterator) CEnumLookup(org.graalvm.nativeimage.c.constant.CEnumLookup) ExceptionHandler(jdk.vm.ci.meta.ExceptionHandler) ProfilingInfo(jdk.vm.ci.meta.ProfilingInfo) SubstrateGraphKit(com.oracle.svm.core.graal.replacements.SubstrateGraphKit) FloatConvert(org.graalvm.compiler.core.common.calc.FloatConvert) LineNumberTable(jdk.vm.ci.meta.LineNumberTable) LocalVariableTable(jdk.vm.ci.meta.LocalVariableTable) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) DeadEndNode(com.oracle.svm.core.graal.nodes.DeadEndNode) LeaveAction(com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode.LeaveAction) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) CEnumValue(org.graalvm.nativeimage.c.constant.CEnumValue) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) ElementInfo(com.oracle.svm.hosted.c.info.ElementInfo) EnumInfo(com.oracle.svm.hosted.c.info.EnumInfo) CEntryPointLeaveNode(com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) CEnum(org.graalvm.nativeimage.c.constant.CEnum) ValueNode(org.graalvm.compiler.nodes.ValueNode) CInterfaceEnumTool(com.oracle.svm.hosted.phases.CInterfaceEnumTool) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) DeadEndNode(com.oracle.svm.core.graal.nodes.DeadEndNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 30 with JavaType

use of jdk.vm.ci.meta.JavaType in project graal by oracle.

the class CEntryPointCallStubMethod method matchPrologueParameters.

private ValueNode[] matchPrologueParameters(HostedProviders providers, JavaType[] types, ValueNode[] values, ResolvedJavaMethod prologueMethod) {
    JavaType[] prologueTypes = prologueMethod.toParameterTypes();
    ValueNode[] prologueValues = new ValueNode[prologueTypes.length];
    int i = 0;
    for (int p = 0; p < prologueTypes.length; p++) {
        ResolvedJavaType prologueType = (ResolvedJavaType) prologueTypes[p];
        UserError.guarantee(prologueType.isPrimitive() || providers.getWordTypes().isWord(prologueType), "Prologue method parameter types are restricted to primitive types and word types: " + targetMethod.format("%H.%n(%p)") + " -> " + prologueMethod.format("%H.%n(%p)"));
        while (i < types.length && !prologueType.isAssignableFrom((ResolvedJavaType) types[i])) {
            i++;
        }
        if (i >= types.length) {
            throw UserError.abort("Unable to match signature of entry point method to that of prologue method: " + targetMethod.format("%H.%n(%p)") + " -> " + prologueMethod.format("%H.%n(%p)"));
        }
        prologueValues[p] = values[i];
        i++;
    }
    return prologueValues;
}
Also used : ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) ValueNode(org.graalvm.compiler.nodes.ValueNode) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Aggregations

JavaType (jdk.vm.ci.meta.JavaType)45 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)35 ValueNode (org.graalvm.compiler.nodes.ValueNode)22 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)15 JavaKind (jdk.vm.ci.meta.JavaKind)14 Signature (jdk.vm.ci.meta.Signature)11 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)8 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)8 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)8 InvokeKind (org.graalvm.compiler.nodes.CallTargetNode.InvokeKind)7 EnumInfo (com.oracle.svm.hosted.c.info.EnumInfo)6 ArrayList (java.util.ArrayList)6 InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)6 CEntryPoint (org.graalvm.nativeimage.c.function.CEntryPoint)6 NativeLibraries (com.oracle.svm.hosted.c.NativeLibraries)5 StampPair (org.graalvm.compiler.core.common.type.StampPair)5 CEntryPointOptions (com.oracle.svm.core.c.function.CEntryPointOptions)4 ElementInfo (com.oracle.svm.hosted.c.info.ElementInfo)4 HostedGraphKit (com.oracle.svm.hosted.phases.HostedGraphKit)4 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)4