Search in sources :

Example 6 with StructFieldInfo

use of com.oracle.svm.hosted.c.info.StructFieldInfo in project graal by oracle.

the class JNIJavaCallWrapperMethod method loadAndUnboxArguments.

private List<Pair<ValueNode, ResolvedJavaType>> loadAndUnboxArguments(JNIGraphKit kit, HostedProviders providers, ResolvedJavaMethod invokeMethod, Signature invokeSignature) {
    MetaAccessProvider metaAccess = providers.getMetaAccess();
    List<Pair<ValueNode, ResolvedJavaType>> args = new ArrayList<>();
    int javaIndex = 0;
    javaIndex += metaAccess.lookupJavaType(JNIEnvironment.class).getJavaKind().getSlotCount();
    if (!invokeMethod.isStatic()) {
        JavaKind kind = metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind();
        ValueNode handle = kit.loadLocal(javaIndex, kind);
        ValueNode unboxed = kit.unboxHandle(handle);
        ValueNode receiver;
        ResolvedJavaType receiverClass = invokeMethod.getDeclaringClass();
        if (invokeMethod.isConstructor()) {
            /*
                 * Our target method is a constructor and we might be called via `NewObject`, in
                 * which case we need to allocate the object before calling the constructor. We can
                 * detect when this is the case because unlike with `Call<Type>Method`, we are
                 * passed the object hub of our target class in place of the receiver object.
                 */
            Constant hub = providers.getConstantReflection().asObjectHub(receiverClass);
            ConstantNode hubNode = kit.createConstant(hub, JavaKind.Object);
            kit.startIf(kit.unique(new ObjectEqualsNode(unboxed, hubNode)), BranchProbabilityNode.FAST_PATH_PROBABILITY);
            kit.thenPart();
            ValueNode created = kit.append(new NewInstanceNode(receiverClass, true));
            AbstractMergeNode merge = kit.endIf();
            receiver = kit.unique(new ValuePhiNode(StampFactory.object(), merge, new ValueNode[] { created, unboxed }));
        } else {
            receiver = unboxed;
        }
        args.add(Pair.create(receiver, receiverClass));
    }
    javaIndex += metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind().getSlotCount();
    if (nonVirtual) {
        javaIndex += metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind().getSlotCount();
    }
    javaIndex += metaAccess.lookupJavaType(JNIMethodId.class).getJavaKind().getSlotCount();
    int count = invokeSignature.getParameterCount(false);
    if (callVariant == CallVariant.VARARGS) {
        for (int i = 0; i < count; i++) {
            ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
            JavaKind kind = type.getJavaKind();
            JavaKind loadKind = kind;
            if (loadKind == JavaKind.Float) {
                // C varargs promote float to double
                loadKind = JavaKind.Double;
            }
            ValueNode value = kit.loadLocal(javaIndex, loadKind);
            if (kind == JavaKind.Float) {
                value = kit.unique(new FloatConvertNode(FloatConvert.D2F, value));
            } else if (kind.isObject()) {
                value = kit.unboxHandle(value);
            }
            args.add(Pair.create(value, type));
            javaIndex += loadKind.getSlotCount();
        }
    } else if (callVariant == CallVariant.ARRAY) {
        ResolvedJavaType elementType = metaAccess.lookupJavaType(JNIValue.class);
        int elementSize = SizeOf.get(JNIValue.class);
        ValueNode array = kit.loadLocal(javaIndex, elementType.getJavaKind());
        for (int i = 0; i < count; i++) {
            ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
            JavaKind readKind = type.getJavaKind();
            StructFieldInfo fieldInfo = getJNIValueOffsetOf(elementType, readKind);
            int offset = i * elementSize + fieldInfo.getOffsetInfo().getProperty();
            ConstantNode offsetConstant = kit.createConstant(JavaConstant.forInt(offset), providers.getWordTypes().getWordKind());
            OffsetAddressNode address = kit.unique(new OffsetAddressNode(array, offsetConstant));
            LocationIdentity locationIdentity = fieldInfo.getLocationIdentity();
            if (locationIdentity == null) {
                locationIdentity = LocationIdentity.any();
            }
            Stamp readStamp = getNarrowStamp(providers, readKind);
            ValueNode value = kit.append(new CInterfaceReadNode(address, locationIdentity, readStamp, BarrierType.NONE, "args[" + i + "]"));
            JavaKind stackKind = readKind.getStackKind();
            if (readKind != stackKind) {
                assert stackKind.getBitCount() > readKind.getBitCount() : "read kind must be narrower than stack kind";
                if (readKind.isUnsigned()) {
                    // needed or another op may illegally sign-extend
                    value = kit.unique(new ZeroExtendNode(value, stackKind.getBitCount()));
                } else {
                    value = kit.unique(new SignExtendNode(value, stackKind.getBitCount()));
                }
            } else if (readKind.isObject()) {
                value = kit.unboxHandle(value);
            }
            args.add(Pair.create(value, type));
        }
    } else if (callVariant == CallVariant.VA_LIST) {
        ValueNode valist = kit.loadLocal(javaIndex, metaAccess.lookupJavaType(WordBase.class).getJavaKind());
        for (int i = 0; i < count; i++) {
            ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
            JavaKind loadKind = type.getJavaKind();
            if (loadKind.isObject()) {
                loadKind = providers.getWordTypes().getWordKind();
            }
            ValueNode value = kit.append(new VaListNextArgNode(loadKind, valist));
            if (type.getJavaKind().isObject()) {
                value = kit.unboxHandle(value);
            }
            args.add(Pair.create(value, type));
        }
    } else {
        throw VMError.unsupportedFeature("Call variant: " + callVariant);
    }
    return args;
}
Also used : NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) Constant(jdk.vm.ci.meta.Constant) JavaConstant(jdk.vm.ci.meta.JavaConstant) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) CInterfaceReadNode(com.oracle.svm.core.graal.nodes.CInterfaceReadNode) ArrayList(java.util.ArrayList) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) JNIValue(com.oracle.svm.jni.nativeapi.JNIValue) LocationIdentity(org.graalvm.word.LocationIdentity) JNIObjectHandle(com.oracle.svm.jni.nativeapi.JNIObjectHandle) Pair(org.graalvm.collections.Pair) JavaKind(jdk.vm.ci.meta.JavaKind) VaListNextArgNode(com.oracle.svm.core.graal.nodes.VaListNextArgNode) Stamp(org.graalvm.compiler.core.common.type.Stamp) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) StructFieldInfo(com.oracle.svm.hosted.c.info.StructFieldInfo) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) JNIMethodId(com.oracle.svm.jni.nativeapi.JNIMethodId) FloatConvertNode(org.graalvm.compiler.nodes.calc.FloatConvertNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) JNIEnvironment(com.oracle.svm.jni.nativeapi.JNIEnvironment) ValueNode(org.graalvm.compiler.nodes.ValueNode) MetaAccessProvider(jdk.vm.ci.meta.MetaAccessProvider)

Example 7 with StructFieldInfo

use of com.oracle.svm.hosted.c.info.StructFieldInfo in project graal by oracle.

the class RawStructureLayoutPlanner method visitRawStructureInfo.

@Override
protected void visitRawStructureInfo(RawStructureInfo info) {
    if (info.isPlanned()) {
        return;
    }
    ResolvedJavaType type = (ResolvedJavaType) info.getAnnotatedElement();
    for (ResolvedJavaType t : type.getInterfaces()) {
        if (!nativeLibs.isPointerBase(t)) {
            throw UserError.abort("Type " + type + " must not implement " + t);
        }
        if (t.equals(nativeLibs.getPointerBaseType())) {
            continue;
        }
        ElementInfo einfo = nativeLibs.findElementInfo(t);
        if (!(einfo instanceof RawStructureInfo)) {
            throw UserError.abort(new CInterfaceError("Illegal super type " + t + " found", type).getMessage());
        }
        RawStructureInfo rinfo = (RawStructureInfo) einfo;
        rinfo.accept(this);
        assert rinfo.isPlanned();
        if (info.getParentInfo() != null) {
            throw UserError.abort(new CInterfaceError("Only single inheritance of RawStructure types is supported", type).getMessage());
        }
        info.setParentInfo(rinfo);
    }
    for (ElementInfo child : new ArrayList<>(info.getChildren())) {
        if (child instanceof StructFieldInfo) {
            StructFieldInfo fieldInfo = (StructFieldInfo) child;
            StructFieldInfo parentFieldInfo = findParentFieldInfo(fieldInfo, info.getParentInfo());
            if (parentFieldInfo != null) {
                fieldInfo.mergeChildrenAndDelete(parentFieldInfo);
            } else {
                computeSize(fieldInfo);
            }
        }
    }
    planLayout(info);
}
Also used : CInterfaceError(com.oracle.svm.hosted.c.CInterfaceError) RawStructureInfo(com.oracle.svm.hosted.c.info.RawStructureInfo) ElementInfo(com.oracle.svm.hosted.c.info.ElementInfo) ArrayList(java.util.ArrayList) StructFieldInfo(com.oracle.svm.hosted.c.info.StructFieldInfo) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Aggregations

StructFieldInfo (com.oracle.svm.hosted.c.info.StructFieldInfo)7 ElementInfo (com.oracle.svm.hosted.c.info.ElementInfo)3 ArrayList (java.util.ArrayList)3 CInterfaceError (com.oracle.svm.hosted.c.CInterfaceError)2 HostedMethod (com.oracle.svm.hosted.meta.HostedMethod)2 HostedType (com.oracle.svm.hosted.meta.HostedType)2 JavaKind (jdk.vm.ci.meta.JavaKind)2 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)2 ValueNode (org.graalvm.compiler.nodes.ValueNode)2 CEntryPoint (org.graalvm.nativeimage.c.function.CEntryPoint)2 CFunctionPointer (org.graalvm.nativeimage.c.function.CFunctionPointer)2 LocationIdentity (org.graalvm.word.LocationIdentity)2 AnalysisMethod (com.oracle.graal.pointsto.meta.AnalysisMethod)1 AnalysisUniverse (com.oracle.graal.pointsto.meta.AnalysisUniverse)1 CInterfaceLocationIdentity (com.oracle.svm.core.c.struct.CInterfaceLocationIdentity)1 CInterfaceReadNode (com.oracle.svm.core.graal.nodes.CInterfaceReadNode)1 VaListNextArgNode (com.oracle.svm.core.graal.nodes.VaListNextArgNode)1 RawStructureInfo (com.oracle.svm.hosted.c.info.RawStructureInfo)1 StructBitfieldInfo (com.oracle.svm.hosted.c.info.StructBitfieldInfo)1 StructInfo (com.oracle.svm.hosted.c.info.StructInfo)1