Search in sources :

Example 1 with NewInstanceNode

use of org.graalvm.compiler.nodes.java.NewInstanceNode in project graal by oracle.

the class ObjectCloneNode method getLoweredSnippetGraph.

@Override
@SuppressWarnings("try")
protected StructuredGraph getLoweredSnippetGraph(LoweringTool tool) {
    ResolvedJavaType type = StampTool.typeOrNull(getObject());
    if (type != null) {
        if (type.isArray()) {
            Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getJavaKind());
            if (method != null) {
                final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method);
                final Replacements replacements = tool.getReplacements();
                StructuredGraph snippetGraph = null;
                DebugContext debug = getDebug();
                try (DebugContext.Scope s = debug.scope("ArrayCloneSnippet", snippetMethod)) {
                    snippetGraph = replacements.getSnippet(snippetMethod, null, graph().trackNodeSourcePosition(), this.getNodeSourcePosition());
                } catch (Throwable e) {
                    throw debug.handle(e);
                }
                assert snippetGraph != null : "ObjectCloneSnippets should be installed";
                assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
                return lowerReplacement((StructuredGraph) snippetGraph.copy(getDebug()), tool);
            }
            assert false : "unhandled array type " + type.getComponentType().getJavaKind();
        } else {
            Assumptions assumptions = graph().getAssumptions();
            type = getConcreteType(getObject().stamp(NodeView.DEFAULT));
            if (type != null) {
                StructuredGraph newGraph = new StructuredGraph.Builder(graph().getOptions(), graph().getDebug(), AllowAssumptions.ifNonNull(assumptions)).build();
                ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp(NodeView.DEFAULT))));
                NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
                newGraph.addAfterFixed(newGraph.start(), newInstance);
                ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance));
                newGraph.addAfterFixed(newInstance, returnNode);
                for (ResolvedJavaField field : type.getInstanceFields(true)) {
                    LoadFieldNode load = newGraph.add(LoadFieldNode.create(newGraph.getAssumptions(), param, field));
                    newGraph.addBeforeFixed(returnNode, load);
                    newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load)));
                }
                assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
                return lowerReplacement(newGraph, tool);
            }
        }
    }
    assert getConcreteType(stamp(NodeView.DEFAULT)) == null;
    return null;
}
Also used : StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Replacements(org.graalvm.compiler.nodes.spi.Replacements) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) Method(java.lang.reflect.Method) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) DebugContext(org.graalvm.compiler.debug.DebugContext) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) AllowAssumptions(org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions) Assumptions(jdk.vm.ci.meta.Assumptions) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 2 with NewInstanceNode

use of org.graalvm.compiler.nodes.java.NewInstanceNode in project graal by oracle.

the class MethodTypeFlowBuilder method registerUsedElements.

public static void registerUsedElements(BigBang bb, StructuredGraph graph, MethodTypeFlow methodFlow) {
    for (Node n : graph.getNodes()) {
        if (n instanceof InstanceOfNode) {
            InstanceOfNode node = (InstanceOfNode) n;
            AnalysisType type = (AnalysisType) node.type().getType();
            type.registerAsInTypeCheck();
        } else if (n instanceof NewInstanceNode) {
            NewInstanceNode node = (NewInstanceNode) n;
            AnalysisType type = (AnalysisType) node.instanceClass();
            type.registerAsAllocated(node);
        } else if (n instanceof NewArrayNode) {
            NewArrayNode node = (NewArrayNode) n;
            AnalysisType type = ((AnalysisType) node.elementType()).getArrayClass();
            type.registerAsAllocated(node);
        } else if (n instanceof NewMultiArrayNode) {
            NewMultiArrayNode node = (NewMultiArrayNode) n;
            AnalysisType type = ((AnalysisType) node.type());
            for (int i = 0; i < node.dimensionCount(); i++) {
                type.registerAsAllocated(node);
                type = type.getComponentType();
            }
        } else if (n instanceof BoxNode) {
            BoxNode node = (BoxNode) n;
            AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
            type.registerAsAllocated(node);
        } else if (n instanceof LoadFieldNode) {
            LoadFieldNode node = (LoadFieldNode) n;
            AnalysisField field = (AnalysisField) node.field();
            field.registerAsRead(methodFlow);
        } else if (n instanceof StoreFieldNode) {
            StoreFieldNode node = (StoreFieldNode) n;
            AnalysisField field = (AnalysisField) node.field();
            field.registerAsWritten(methodFlow);
        } else if (n instanceof StoreIndexedNode) {
            StoreIndexedNode node = (StoreIndexedNode) n;
            AnalysisType arrayType = (AnalysisType) StampTool.typeOrNull(node.array());
            if (arrayType != null) {
                assert arrayType.isArray();
                arrayType.getComponentType().registerAsInTypeCheck();
            }
        } else if (n instanceof BytecodeExceptionNode) {
            BytecodeExceptionNode node = (BytecodeExceptionNode) n;
            AnalysisType type = bb.getMetaAccess().lookupJavaType(node.getExceptionClass());
            type.registerAsInHeap();
        } else if (n instanceof ConstantNode) {
            ConstantNode cn = (ConstantNode) n;
            if (cn.hasUsages() && cn.asJavaConstant().getJavaKind() == JavaKind.Object && cn.asJavaConstant().isNonNull()) {
                assert StampTool.isExactType(cn);
                AnalysisType type = (AnalysisType) StampTool.typeOrNull(cn);
                type.registerAsInHeap();
            }
        } else if (n instanceof ForeignCallNode) {
            ForeignCallNode node = (ForeignCallNode) n;
            registerForeignCall(bb, node.getDescriptor());
        } else if (n instanceof UnaryMathIntrinsicNode) {
            UnaryMathIntrinsicNode node = (UnaryMathIntrinsicNode) n;
            registerForeignCall(bb, node.getOperation().foreignCallDescriptor);
        } else if (n instanceof BinaryMathIntrinsicNode) {
            BinaryMathIntrinsicNode node = (BinaryMathIntrinsicNode) n;
            registerForeignCall(bb, node.getOperation().foreignCallDescriptor);
        }
    }
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) DynamicNewInstanceNode(org.graalvm.compiler.nodes.java.DynamicNewInstanceNode) DynamicNewArrayNode(org.graalvm.compiler.nodes.java.DynamicNewArrayNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) UnaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode) RawLoadNode(org.graalvm.compiler.nodes.extended.RawLoadNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) WordCastNode(org.graalvm.compiler.word.WordCastNode) DynamicNewArrayNode(org.graalvm.compiler.nodes.java.DynamicNewArrayNode) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) BasicObjectCloneNode(org.graalvm.compiler.replacements.nodes.BasicObjectCloneNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) AtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode) ConvertUnknownValueNode(com.oracle.graal.pointsto.nodes.ConvertUnknownValueNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AnalysisUnsafePartitionLoadNode(com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionLoadNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) AnalysisArraysCopyOfNode(com.oracle.graal.pointsto.nodes.AnalysisArraysCopyOfNode) DynamicNewInstanceNode(org.graalvm.compiler.nodes.java.DynamicNewInstanceNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) NewMultiArrayNode(org.graalvm.compiler.nodes.java.NewMultiArrayNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) BinaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode) IfNode(org.graalvm.compiler.nodes.IfNode) RawStoreNode(org.graalvm.compiler.nodes.extended.RawStoreNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) UnsafeCompareAndSwapNode(org.graalvm.compiler.nodes.java.UnsafeCompareAndSwapNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) BasicArrayCopyNode(org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) UnaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) GetClassNode(org.graalvm.compiler.nodes.extended.GetClassNode) BytecodeExceptionNode(org.graalvm.compiler.nodes.extended.BytecodeExceptionNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) AnalysisUnsafePartitionStoreNode(com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionStoreNode) BytecodeExceptionNode(org.graalvm.compiler.nodes.extended.BytecodeExceptionNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) AnalysisField(com.oracle.graal.pointsto.meta.AnalysisField) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) BinaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) NewMultiArrayNode(org.graalvm.compiler.nodes.java.NewMultiArrayNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode)

Example 3 with NewInstanceNode

use of org.graalvm.compiler.nodes.java.NewInstanceNode in project graal by oracle.

the class PEGraphDecoder method canonicalizeFixedNode.

@SuppressWarnings("try")
@Override
protected Node canonicalizeFixedNode(MethodScope s, Node node) {
    PEMethodScope methodScope = (PEMethodScope) s;
    Node replacedNode = node;
    if (nodePlugins != null && nodePlugins.length > 0) {
        if (node instanceof LoadFieldNode) {
            LoadFieldNode loadFieldNode = (LoadFieldNode) node;
            PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, loadFieldNode);
            ResolvedJavaField field = loadFieldNode.field();
            if (loadFieldNode.isStatic()) {
                for (NodePlugin nodePlugin : nodePlugins) {
                    if (nodePlugin.handleLoadStaticField(graphBuilderContext, field)) {
                        replacedNode = graphBuilderContext.pushedNode;
                        break;
                    }
                }
            } else {
                ValueNode object = loadFieldNode.object();
                for (NodePlugin nodePlugin : nodePlugins) {
                    if (nodePlugin.handleLoadField(graphBuilderContext, object, field)) {
                        replacedNode = graphBuilderContext.pushedNode;
                        break;
                    }
                }
            }
        } else if (node instanceof StoreFieldNode) {
            StoreFieldNode storeFieldNode = (StoreFieldNode) node;
            PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, storeFieldNode);
            ResolvedJavaField field = storeFieldNode.field();
            if (storeFieldNode.isStatic()) {
                ValueNode value = storeFieldNode.value();
                for (NodePlugin nodePlugin : nodePlugins) {
                    if (nodePlugin.handleStoreStaticField(graphBuilderContext, field, value)) {
                        replacedNode = graphBuilderContext.pushedNode;
                        break;
                    }
                }
            } else {
                ValueNode object = storeFieldNode.object();
                ValueNode value = storeFieldNode.value();
                for (NodePlugin nodePlugin : nodePlugins) {
                    if (nodePlugin.handleStoreField(graphBuilderContext, object, field, value)) {
                        replacedNode = graphBuilderContext.pushedNode;
                        break;
                    }
                }
            }
        } else if (node instanceof LoadIndexedNode) {
            LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
            PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, loadIndexedNode);
            ValueNode array = loadIndexedNode.array();
            ValueNode index = loadIndexedNode.index();
            for (NodePlugin nodePlugin : nodePlugins) {
                if (nodePlugin.handleLoadIndexed(graphBuilderContext, array, index, loadIndexedNode.elementKind())) {
                    replacedNode = graphBuilderContext.pushedNode;
                    break;
                }
            }
        } else if (node instanceof StoreIndexedNode) {
            StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node;
            PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, storeIndexedNode);
            ValueNode array = storeIndexedNode.array();
            ValueNode index = storeIndexedNode.index();
            ValueNode value = storeIndexedNode.value();
            for (NodePlugin nodePlugin : nodePlugins) {
                if (nodePlugin.handleStoreIndexed(graphBuilderContext, array, index, storeIndexedNode.elementKind(), value)) {
                    replacedNode = graphBuilderContext.pushedNode;
                    break;
                }
            }
        } else if (node instanceof NewInstanceNode) {
            NewInstanceNode newInstanceNode = (NewInstanceNode) node;
            PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newInstanceNode);
            ResolvedJavaType type = newInstanceNode.instanceClass();
            for (NodePlugin nodePlugin : nodePlugins) {
                if (nodePlugin.handleNewInstance(graphBuilderContext, type)) {
                    replacedNode = graphBuilderContext.pushedNode;
                    break;
                }
            }
        } else if (node instanceof NewArrayNode) {
            NewArrayNode newArrayNode = (NewArrayNode) node;
            PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newArrayNode);
            ResolvedJavaType elementType = newArrayNode.elementType();
            ValueNode length = newArrayNode.length();
            for (NodePlugin nodePlugin : nodePlugins) {
                if (nodePlugin.handleNewArray(graphBuilderContext, elementType, length)) {
                    replacedNode = graphBuilderContext.pushedNode;
                    break;
                }
            }
        } else if (node instanceof NewMultiArrayNode) {
            NewMultiArrayNode newArrayNode = (NewMultiArrayNode) node;
            PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newArrayNode);
            ResolvedJavaType elementType = newArrayNode.type();
            ValueNode[] dimensions = newArrayNode.dimensions().toArray(new ValueNode[0]);
            for (NodePlugin nodePlugin : nodePlugins) {
                if (nodePlugin.handleNewMultiArray(graphBuilderContext, elementType, dimensions)) {
                    replacedNode = graphBuilderContext.pushedNode;
                    break;
                }
            }
        }
    }
    return super.canonicalizeFixedNode(methodScope, replacedNode);
}
Also used : StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) NewMultiArrayNode(org.graalvm.compiler.nodes.java.NewMultiArrayNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) IntegerSwitchNode(org.graalvm.compiler.nodes.extended.IntegerSwitchNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) NewMultiArrayNode(org.graalvm.compiler.nodes.java.NewMultiArrayNode) NodePlugin(org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 4 with NewInstanceNode

use of org.graalvm.compiler.nodes.java.NewInstanceNode 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 5 with NewInstanceNode

use of org.graalvm.compiler.nodes.java.NewInstanceNode 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)

Aggregations

NewInstanceNode (org.graalvm.compiler.nodes.java.NewInstanceNode)11 ValueNode (org.graalvm.compiler.nodes.ValueNode)8 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)7 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)5 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)5 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)5 DebugContext (org.graalvm.compiler.debug.DebugContext)4 Node (org.graalvm.compiler.graph.Node)4 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)4 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)4 UnwindNode (org.graalvm.compiler.nodes.UnwindNode)4 NewArrayNode (org.graalvm.compiler.nodes.java.NewArrayNode)4 JavaConstant (jdk.vm.ci.meta.JavaConstant)3 JavaKind (jdk.vm.ci.meta.JavaKind)3 MetaAccessProvider (jdk.vm.ci.meta.MetaAccessProvider)3 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)3 LoadFieldNode (org.graalvm.compiler.nodes.java.LoadFieldNode)3 StoreFieldNode (org.graalvm.compiler.nodes.java.StoreFieldNode)3 HostedProviders (com.oracle.graal.pointsto.meta.HostedProviders)2 UserError (com.oracle.svm.core.util.UserError)2