Search in sources :

Example 31 with RequiredInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.

the class SubstrateGraphBuilderPlugins method registerKnownIntrinsicsPlugins.

private static void registerKnownIntrinsicsPlugins(InvocationPlugins plugins) {
    Registration r = new Registration(plugins, KnownIntrinsics.class);
    r.register(new RequiredInvocationPlugin("heapBase") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Object, ReadReservedRegister.createReadHeapBaseNode(b.getGraph()));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("readHub", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            ValueNode nonNullObject = b.nullCheckedValue(object);
            b.addPush(JavaKind.Object, new LoadHubNode(b.getStampProvider(), nonNullObject));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("nonNullPointer", Pointer.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.addPush(JavaKind.Object, new PiNode(object, nonZeroWord()));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("readStackPointer") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Object, ReadReservedRegister.createReadStackPointerNode(b.getGraph()));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("readCallerStackPointer") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            checkNeverInline(b);
            b.addPush(JavaKind.Object, new ReadCallerStackPointerNode());
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("readReturnAddress") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            checkNeverInline(b);
            b.addPush(JavaKind.Object, new ReadReturnAddressNode());
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("farReturn", Object.class, Pointer.class, CodePointer.class, boolean.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode result, ValueNode sp, ValueNode ip, ValueNode fromMethodWithCalleeSavedRegisters) {
            if (!fromMethodWithCalleeSavedRegisters.isConstant()) {
                throw b.bailout("parameter fromMethodWithCalleeSavedRegisters is not a compile time constant for call to " + targetMethod.format("%H.%n(%p)") + " in " + b.getMethod().asStackTraceElement(b.bci()));
            }
            b.add(new FarReturnNode(result, sp, ip, fromMethodWithCalleeSavedRegisters.asJavaConstant().asInt() != 0));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("testDeoptimize") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new TestDeoptimizeNode());
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("isDeoptimizationTarget") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            if (SubstrateOptions.parseOnce()) {
                throw VMError.unimplemented("Intrinsification of isDeoptimizationTarget not done yet");
            }
            if (b.getGraph().method() instanceof SharedMethod) {
                SharedMethod method = (SharedMethod) b.getGraph().method();
                if (method.isDeoptTarget()) {
                    b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
                } else {
                    b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
                }
            } else {
                // In analysis the value is always true.
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            }
            return true;
        }
    });
    registerCastExact(r);
}
Also used : ReadCallerStackPointerNode(com.oracle.svm.core.graal.nodes.ReadCallerStackPointerNode) TestDeoptimizeNode(com.oracle.svm.core.graal.nodes.TestDeoptimizeNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) RequiredInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) CodePointer(org.graalvm.nativeimage.c.function.CodePointer) Pointer(org.graalvm.word.Pointer) DynamicPiNode(org.graalvm.compiler.nodes.DynamicPiNode) PiNode(org.graalvm.compiler.nodes.PiNode) CodePointer(org.graalvm.nativeimage.c.function.CodePointer) ReadReturnAddressNode(com.oracle.svm.core.graal.nodes.ReadReturnAddressNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) FarReturnNode(com.oracle.svm.core.graal.nodes.FarReturnNode) StackValueNode(com.oracle.svm.core.graal.stackvalue.StackValueNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) SharedMethod(com.oracle.svm.core.meta.SharedMethod) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 32 with RequiredInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.

the class SubstrateGraphBuilderPlugins method registerUnsafePlugins.

private static void registerUnsafePlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins, SnippetReflectionProvider snippetReflection, ParsingReason reason) {
    registerUnsafePlugins(metaAccess, new Registration(plugins, sun.misc.Unsafe.class), snippetReflection, reason, true);
    Registration r = new Registration(plugins, "jdk.internal.misc.Unsafe");
    registerUnsafePlugins(metaAccess, r, snippetReflection, reason, false);
    r.register(new RequiredInvocationPlugin("objectFieldOffset", Receiver.class, Class.class, String.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode classNode, ValueNode nameNode) {
            if (classNode.isConstant() && nameNode.isConstant()) {
                /* If the class and field name arguments are constant. */
                Class<?> clazz = snippetReflection.asObject(Class.class, classNode.asJavaConstant());
                String fieldName = snippetReflection.asObject(String.class, nameNode.asJavaConstant());
                try {
                    Field targetField = clazz.getDeclaredField(fieldName);
                    return processFieldOffset(b, targetField, reason, metaAccess, false);
                } catch (NoSuchFieldException | LinkageError e) {
                    return false;
                }
            }
            return false;
        }
    });
    r.register(new RequiredInvocationPlugin("allocateUninitializedArray", Receiver.class, Class.class, int.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode componentTypeNode, ValueNode lengthNode) {
            /*
                 * For simplicity, we only intrinsify if the componentType is a compile-time
                 * constant. That also allows us to constant-fold the required check that the
                 * component type is a primitive type.
                 */
            if (!componentTypeNode.isJavaConstant() || componentTypeNode.asJavaConstant().isNull()) {
                return false;
            }
            ResolvedJavaType componentType = b.getConstantReflection().asJavaType(componentTypeNode.asJavaConstant());
            if (componentType == null || !componentType.isPrimitive()) {
                return false;
            }
            /* Emits a null-check for the otherwise unused receiver. */
            unsafe.get();
            /*
                 * Note that allocateUninitializedArray must throw a IllegalArgumentException, and
                 * not a NegativeArraySizeException, when the length is negative.
                 */
            ValueNode lengthPositive = b.maybeEmitExplicitNegativeArraySizeCheck(lengthNode, BytecodeExceptionNode.BytecodeExceptionKind.ILLEGAL_ARGUMENT_EXCEPTION_NEGATIVE_LENGTH);
            b.addPush(JavaKind.Object, new NewArrayNode(componentType, lengthPositive, false));
            return true;
        }
    });
}
Also used : NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) RequiredInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) AnalysisField(com.oracle.graal.pointsto.meta.AnalysisField) Field(java.lang.reflect.Field) SharedField(com.oracle.svm.core.meta.SharedField) HostedField(com.oracle.svm.hosted.meta.HostedField) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) StackValueNode(com.oracle.svm.core.graal.stackvalue.StackValueNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 33 with RequiredInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.

the class ReflectionPlugins method registerFoldInvocationPlugin.

private void registerFoldInvocationPlugin(InvocationPlugins plugins, Method reflectionMethod) {
    if (!ALLOWED_CONSTANT_CLASSES.contains(reflectionMethod.getReturnType()) && !reflectionMethod.getReturnType().isPrimitive()) {
        throw VMError.shouldNotReachHere("Return type of method " + reflectionMethod + " is not on the allow-list for types that are immutable");
    }
    reflectionMethod.setAccessible(true);
    List<Class<?>> parameterTypes = new ArrayList<>();
    if (!Modifier.isStatic(reflectionMethod.getModifiers())) {
        parameterTypes.add(Receiver.class);
    }
    parameterTypes.addAll(Arrays.asList(reflectionMethod.getParameterTypes()));
    plugins.register(reflectionMethod.getDeclaringClass(), new RequiredInvocationPlugin(reflectionMethod.getName(), parameterTypes.toArray(new Class<?>[0])) {

        @Override
        public boolean defaultHandler(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode... args) {
            return foldInvocationUsingReflection(b, targetMethod, reflectionMethod, receiver, args);
        }
    });
}
Also used : GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) RequiredInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin) ArrayList(java.util.ArrayList) ValueNode(org.graalvm.compiler.nodes.ValueNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 34 with RequiredInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.

the class VMThreadSTFeature method registerInvocationPlugins.

/**
 * Intrinsify the {@code get()} and {@code set()} methods during bytecode parsing. We know that
 * every subclass of VMThreadLocal has the same methods. Only the signatures differ based on the
 * type of value.
 * <p>
 * The value is stored in the two arrays that are in the image heap: a Object[] array for thread
 * local object variables, and a byte[] array for all thread local primitive variables.
 * Therefore, we need the proper read/write barriers. The {@link IsolateThread} parameter is
 * ignored.
 */
@Override
public void registerInvocationPlugins(Providers providers, SnippetReflectionProvider snippetReflection, Plugins plugins, ParsingReason reason) {
    for (Class<? extends FastThreadLocal> threadLocalClass : VMThreadLocalInfo.THREAD_LOCAL_CLASSES) {
        Registration r = new Registration(plugins.getInvocationPlugins(), threadLocalClass);
        Class<?> valueClass = VMThreadLocalInfo.getValueClass(threadLocalClass);
        registerAccessors(r, valueClass, false);
        registerAccessors(r, valueClass, true);
        /* compareAndSet() method without the VMThread parameter. */
        r.register(new RequiredInvocationPlugin("compareAndSet", Receiver.class, valueClass, valueClass) {

            @Override
            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode expect, ValueNode update) {
                return handleCompareAndSet(b, targetMethod, receiver, expect, update);
            }
        });
        /* get() method with the VMThread parameter. */
        r.register(new RequiredInvocationPlugin("compareAndSet", Receiver.class, IsolateThread.class, valueClass, valueClass) {

            @Override
            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode threadNode, ValueNode expect, ValueNode update) {
                return handleCompareAndSet(b, targetMethod, receiver, expect, update);
            }
        });
    }
    Class<?>[] typesWithGetAddress = new Class<?>[] { FastThreadLocalBytes.class, FastThreadLocalWord.class };
    for (Class<?> type : typesWithGetAddress) {
        Registration r = new Registration(plugins.getInvocationPlugins(), type);
        /* getAddress() method without the VMThread parameter. */
        r.register(new RequiredInvocationPlugin("getAddress", Receiver.class) {

            @Override
            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                return handleGetAddress(b, targetMethod, receiver);
            }
        });
        /* getAddress() method with the VMThread parameter. */
        r.register(new RequiredInvocationPlugin("getAddress", Receiver.class, IsolateThread.class) {

            @Override
            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode threadNode) {
                return handleGetAddress(b, targetMethod, receiver);
            }
        });
    }
}
Also used : RequiredInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) FastThreadLocalWord(com.oracle.svm.core.threadlocal.FastThreadLocalWord) IsolateThread(org.graalvm.nativeimage.IsolateThread) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) FastThreadLocalBytes(com.oracle.svm.core.threadlocal.FastThreadLocalBytes) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 35 with RequiredInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.

the class VMThreadMTFeature method registerInvocationPlugins.

/**
 * Intrinsify the {@code get()} and {@code set()} methods during bytecode parsing. We know that
 * every subclass of VMThreadLocal has the same methods. Only the signatures differ based on the
 * type of value.
 * <p>
 * When the {@link IsolateThread} is not passed in as a parameter, we use the
 * {@link LoadVMThreadLocalNode current thread}. We do not need read/write barriers since we
 * access memory that we manage ourselfs.
 */
@Override
public void registerInvocationPlugins(Providers providers, SnippetReflectionProvider snippetReflection, Plugins plugins, ParsingReason reason) {
    for (Class<? extends FastThreadLocal> threadLocalClass : VMThreadLocalInfo.THREAD_LOCAL_CLASSES) {
        Registration r = new Registration(plugins.getInvocationPlugins(), threadLocalClass);
        Class<?> valueClass = VMThreadLocalInfo.getValueClass(threadLocalClass);
        registerAccessors(r, valueClass, false);
        registerAccessors(r, valueClass, true);
        /* compareAndSet() method without the VMThread parameter. */
        r.register(new RequiredInvocationPlugin("compareAndSet", Receiver.class, valueClass, valueClass) {

            @Override
            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode expect, ValueNode update) {
                ValueNode threadNode = currentThread(b);
                return handleCompareAndSet(b, targetMethod, receiver, threadNode, expect, update);
            }
        });
        /* get() method with the VMThread parameter. */
        r.register(new RequiredInvocationPlugin("compareAndSet", Receiver.class, IsolateThread.class, valueClass, valueClass) {

            @Override
            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode threadNode, ValueNode expect, ValueNode update) {
                return handleCompareAndSet(b, targetMethod, receiver, threadNode, expect, update);
            }
        });
    }
    Class<?>[] typesWithGetAddress = new Class<?>[] { FastThreadLocalBytes.class, FastThreadLocalWord.class };
    for (Class<?> type : typesWithGetAddress) {
        Registration r = new Registration(plugins.getInvocationPlugins(), type);
        /* getAddress() method without the VMThread parameter. */
        r.register(new RequiredInvocationPlugin("getAddress", Receiver.class) {

            @Override
            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                ValueNode threadNode = currentThread(b);
                return handleGetAddress(b, targetMethod, receiver, threadNode);
            }
        });
        /* getAddress() method with the VMThread parameter. */
        r.register(new RequiredInvocationPlugin("getAddress", Receiver.class, IsolateThread.class) {

            @Override
            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode threadNode) {
                return handleGetAddress(b, targetMethod, receiver, threadNode);
            }
        });
    }
}
Also used : RequiredInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) FastThreadLocalWord(com.oracle.svm.core.threadlocal.FastThreadLocalWord) IsolateThread(org.graalvm.nativeimage.IsolateThread) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) FastThreadLocalBytes(com.oracle.svm.core.threadlocal.FastThreadLocalBytes) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Aggregations

ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)47 GraphBuilderContext (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext)47 RequiredInvocationPlugin (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin)47 ValueNode (org.graalvm.compiler.nodes.ValueNode)38 Receiver (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver)37 Registration (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration)34 StackValueNode (com.oracle.svm.core.graal.stackvalue.StackValueNode)14 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)9 ResolvedJavaSymbol (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.ResolvedJavaSymbol)8 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)6 JavaConstant (jdk.vm.ci.meta.JavaConstant)5 LogicNode (org.graalvm.compiler.nodes.LogicNode)5 InvocationPlugins (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins)5 IsolateThread (org.graalvm.nativeimage.IsolateThread)4 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)3 TruffleCompilerRuntime (org.graalvm.compiler.truffle.common.TruffleCompilerRuntime)3 AllowMaterializeNode (org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode)3 NewFrameNode (org.graalvm.compiler.truffle.compiler.nodes.frame.NewFrameNode)3 VirtualFrameGetNode (org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameGetNode)3 VirtualFrameSetNode (org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameSetNode)3