Search in sources :

Example 1 with HotSpotInvocationPluginHelper

use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.

the class HotSpotGraphBuilderPlugins method registerClassPlugins.

private static void registerClassPlugins(Plugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
    Registration r = new Registration(plugins.getInvocationPlugins(), Class.class, replacements);
    r.register(new InvocationPlugin("getModifiers", Receiver.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                ValueNode klass = helper.readKlassFromClass(receiver.get());
                // Primitive Class case
                ValueNode nonNullKlass = helper.emitNullReturnGuard(klass, ConstantNode.forInt(Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC), GraalDirectives.UNLIKELY_PROBABILITY);
                // other return Klass::_modifier_flags
                helper.emitFinalReturn(JavaKind.Int, helper.readKlassModifierFlags(nonNullKlass));
            }
            return true;
        }
    });
    r.register(new InvocationPlugin("isInterface", Receiver.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                ValueNode klass = helper.readKlassFromClass(receiver.get());
                // Primitive Class case returns false
                ValueNode klassNonNull = helper.emitNullReturnGuard(klass, ConstantNode.forBoolean(false), GraalDirectives.UNLIKELY_PROBABILITY);
                ValueNode accessFlags = helper.readKlassAccessFlags(klassNonNull);
                // return (Klass::_access_flags & Modifier.INTERFACE) == 0 ? false : true
                LogicNode test = IntegerTestNode.create(accessFlags, ConstantNode.forInt(Modifier.INTERFACE), NodeView.DEFAULT);
                helper.emitFinalReturn(JavaKind.Boolean, ConditionalNode.create(test, ConstantNode.forBoolean(false), ConstantNode.forBoolean(true), NodeView.DEFAULT));
            }
            return true;
        }
    });
    r.register(new InvocationPlugin("isPrimitive", Receiver.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                ValueNode klass = helper.readKlassFromClass(receiver.get());
                LogicNode isNull = b.add(IsNullNode.create(klass));
                b.addPush(JavaKind.Boolean, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false)), NodeView.DEFAULT));
            }
            return true;
        }
    });
    r.register(new InvocationPlugin("getSuperclass", Receiver.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                ValueNode klass = helper.readKlassFromClass(receiver.get());
                ConstantNode nullValue = ConstantNode.defaultForKind(JavaKind.Object);
                // Primitive Class case returns null
                PiNode klassNonNull = helper.emitNullReturnGuard(klass, nullValue, GraalDirectives.UNLIKELY_PROBABILITY);
                // if ((Klass::_access_flags & Modifer.INTERCAE) != 0) return null
                ValueNode accessFlags = helper.readKlassAccessFlags(klassNonNull);
                LogicNode test = IntegerTestNode.create(accessFlags, ConstantNode.forInt(Modifier.INTERFACE), NodeView.DEFAULT);
                helper.emitReturnIfNot(test, nullValue, GraalDirectives.UNLIKELY_PROBABILITY);
                // Handle array Class case
                // if (Klass::_layout_helper < 0) return Object.class
                ValueNode layoutHelper = helper.klassLayoutHelper(klassNonNull);
                ResolvedJavaType objectType = b.getMetaAccess().lookupJavaType(Object.class);
                ValueNode objectClass = ConstantNode.forConstant(b.getConstantReflection().asJavaClass(objectType), b.getMetaAccess());
                helper.emitReturnIf(layoutHelper, Condition.LT, ConstantNode.forInt(config.klassLayoutHelperNeutralValue), objectClass, GraalDirectives.UNLIKELY_PROBABILITY);
                // Read Klass::_super
                ValueNode superKlass = helper.readKlassSuperKlass(klassNonNull);
                // Return null if super is null
                PiNode superKlassNonNull = helper.emitNullReturnGuard(superKlass, nullValue, GraalDirectives.UNLIKELY_PROBABILITY);
                // Convert Klass to Class and return
                helper.emitFinalReturn(JavaKind.Object, new HubGetClassNode(b.getMetaAccess(), superKlassNonNull));
            }
            return true;
        }
    });
    r.registerConditional(config.jvmAccIsHiddenClass != 0, new InvocationPlugin("isHidden", Receiver.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                ValueNode klass = helper.readKlassFromClass(receiver.get());
                // Primitive Class case returns false
                ValueNode nonNullKlass = helper.emitNullReturnGuard(klass, ConstantNode.forBoolean(false), GraalDirectives.UNLIKELY_PROBABILITY);
                // return (Klass::_access_flags & jvmAccIsHiddenClass) == 0 ? false : true
                ValueNode accessFlags = helper.readKlassAccessFlags(nonNullKlass);
                LogicNode test = IntegerTestNode.create(accessFlags, ConstantNode.forInt(config.jvmAccIsHiddenClass), NodeView.DEFAULT);
                helper.emitFinalReturn(JavaKind.Boolean, ConditionalNode.create(test, ConstantNode.forBoolean(false), ConstantNode.forBoolean(true), NodeView.DEFAULT));
            }
            return true;
        }
    });
}
Also used : HubGetClassNode(org.graalvm.compiler.hotspot.replacements.HubGetClassNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) PiNode(org.graalvm.compiler.nodes.PiNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) SnippetSubstitutionInvocationPlugin(org.graalvm.compiler.replacements.SnippetSubstitutionInvocationPlugin) InlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.InlineOnlyInvocationPlugin) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) HotSpotInvocationPluginHelper(org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper)

Example 2 with HotSpotInvocationPluginHelper

use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.

the class HotSpotGraphBuilderPlugins method registerReflectionPlugins.

private static void registerReflectionPlugins(InvocationPlugins plugins, Replacements replacements, GraalHotSpotVMConfig config) {
    Registration r = new Registration(plugins, reflectionClass, replacements);
    r.register(new InlineOnlyInvocationPlugin("getCallerClass") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Object, new HotSpotReflectionGetCallerClassNode(MacroParams.of(b, targetMethod)));
            return true;
        }
    });
    r.register(new InvocationPlugin("getClassAccessFlags", Class.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                ValueNode klass = helper.readKlassFromClass(b.nullCheckedValue(arg));
                // Primitive Class case
                ValueNode klassNonNull = helper.emitNullReturnGuard(klass, ConstantNode.forInt(Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC), GraalDirectives.UNLIKELY_PROBABILITY);
                // Return (Klass::_access_flags & jvmAccWrittenFlags)
                ValueNode accessFlags = helper.readKlassAccessFlags(klassNonNull);
                helper.emitFinalReturn(JavaKind.Int, new AndNode(accessFlags, ConstantNode.forInt(config.jvmAccWrittenFlags)));
            }
            return true;
        }
    });
}
Also used : HotSpotReflectionGetCallerClassNode(org.graalvm.compiler.hotspot.replacements.HotSpotReflectionGetCallerClassNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) InlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.InlineOnlyInvocationPlugin) ValueNode(org.graalvm.compiler.nodes.ValueNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) SnippetSubstitutionInvocationPlugin(org.graalvm.compiler.replacements.SnippetSubstitutionInvocationPlugin) InlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.InlineOnlyInvocationPlugin) AndNode(org.graalvm.compiler.nodes.calc.AndNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) HotSpotInvocationPluginHelper(org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper)

Example 3 with HotSpotInvocationPluginHelper

use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.

the class HotSpotGraphBuilderPlugins method registerThreadPlugins.

private static void registerThreadPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
    Registration r = new Registration(plugins, Thread.class, replacements);
    r.register(new InvocationPlugin("currentThread") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                ValueNode value = helper.readCurrentThreadObject();
                b.push(JavaKind.Object, value);
            }
            return true;
        }
    });
    // This substitution is no longer in used when threadObj is a handle
    r.registerConditional(config.osThreadInterruptedOffset != Integer.MAX_VALUE && !config.threadObjectFieldIsHandle, new InvocationPlugin("isInterrupted", Receiver.class, boolean.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clearInterrupted) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                ValueNode receiverThreadObject = receiver.get();
                CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
                ValueNode currentThreadObject = helper.readCurrentThreadObject(thread);
                // if (this != Thread.currentThread()) do fallback
                helper.doFallbackIf(receiverThreadObject, NE, currentThreadObject, GraalDirectives.UNLIKELY_PROBABILITY);
                ValueNode osThread = helper.readOsThread(thread);
                ValueNode interrupted = helper.readOsThreadInterrupted(osThread);
                // if (thread._osthread._isinterrupted == 0) return false
                helper.emitReturnIf(interrupted, EQ, ConstantNode.forInt(0), ConstantNode.forBoolean(false), GraalDirectives.LIKELY_PROBABILITY);
                // if (clearInterrupted) fallback to invoke
                helper.doFallbackIf(clearInterrupted, EQ, ConstantNode.forBoolean(true), GraalDirectives.UNLIKELY_PROBABILITY);
                // return interrupted == 0 ? false : true
                LogicNode test = helper.createCompare(interrupted, CanonicalCondition.EQ, ConstantNode.forInt(0));
                helper.emitFinalReturn(JavaKind.Boolean, ConditionalNode.create(test, ConstantNode.forBoolean(false), ConstantNode.forBoolean(true), NodeView.DEFAULT));
            }
            return true;
        }
    });
}
Also used : GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) SnippetSubstitutionInvocationPlugin(org.graalvm.compiler.replacements.SnippetSubstitutionInvocationPlugin) InlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.InlineOnlyInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) CurrentJavaThreadNode(org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) HotSpotInvocationPluginHelper(org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper)

Example 4 with HotSpotInvocationPluginHelper

use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.

the class HotSpotGraphBuilderPlugins method registerArrayPlugins.

private static void registerArrayPlugins(InvocationPlugins plugins, Replacements replacements, GraalHotSpotVMConfig config) {
    Registration r = new Registration(plugins, Array.class, replacements);
    r.setAllowOverwrite(true);
    r.register(new InvocationPlugin("newInstance", Class.class, int.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode componentType, ValueNode length) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
                // If (componentType == null) then deopt
                ValueNode nonNullComponentType = b.nullCheckedValue(componentType);
                // Read Class.array_klass
                ValueNode arrayClass = helper.loadArrayKlass(nonNullComponentType);
                // Take the fallback path is the array klass is null
                helper.doFallbackIf(IsNullNode.create(arrayClass), GraalDirectives.UNLIKELY_PROBABILITY);
                // Otherwise perform the array allocation
                helper.emitFinalReturn(JavaKind.Object, new DynamicNewArrayNode(nonNullComponentType, length, true));
            }
            return true;
        }
    });
}
Also used : GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) SnippetSubstitutionInvocationPlugin(org.graalvm.compiler.replacements.SnippetSubstitutionInvocationPlugin) InlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.InlineOnlyInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) DynamicNewArrayNode(org.graalvm.compiler.nodes.java.DynamicNewArrayNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) HotSpotInvocationPluginHelper(org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper)

Example 5 with HotSpotInvocationPluginHelper

use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.

the class HotSpotGraphBuilderPlugins method registerStringPlugins.

private static void registerStringPlugins(InvocationPlugins plugins, Replacements replacements, WordTypes wordTypes, ArrayCopyForeignCalls foreignCalls, GraalHotSpotVMConfig vmConfig) {
    final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", replacements);
    utf16r.register(new InvocationPlugin("toBytes", char[].class, int.class, int.class) {

        private static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value, ValueNode srcBegin, ValueNode length) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, vmConfig)) {
                helper.intrinsicRangeCheck(srcBegin, Condition.LT, ConstantNode.forInt(0));
                helper.intrinsicRangeCheck(length, Condition.LT, ConstantNode.forInt(0));
                helper.intrinsicRangeCheck(length, Condition.GT, ConstantNode.forInt(MAX_LENGTH));
                ValueNode valueLength = b.add(new ArrayLengthNode(value));
                ValueNode limit = b.add(new SubNode(valueLength, length));
                helper.intrinsicRangeCheck(srcBegin, Condition.GT, limit);
                ValueNode newArray = b.add(new NewArrayNode(b.getMetaAccess().lookupJavaType(Byte.TYPE), b.add(new LeftShiftNode(length, ConstantNode.forInt(1))), false));
                b.addPush(JavaKind.Object, newArray);
                // The stateAfter should include the value pushed, so push it first and then
                // perform the call that fills in the array.
                b.add(new ArrayCopyCallNode(foreignCalls, wordTypes, value, srcBegin, newArray, ConstantNode.forInt(0), length, JavaKind.Char, LocationIdentity.init(), false, true, true, vmConfig.heapWordSize));
            }
            return true;
        }
    });
    utf16r.register(new InvocationPlugin("getChars", byte[].class, int.class, int.class, char[].class, int.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value, ValueNode srcBegin, ValueNode srcEnd, ValueNode dst, ValueNode dstBegin) {
            try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, vmConfig)) {
                ValueNode length = helper.sub(srcEnd, srcBegin);
                helper.intrinsicRangeCheck(srcBegin, Condition.LT, ConstantNode.forInt(0));
                helper.intrinsicRangeCheck(length, Condition.LT, ConstantNode.forInt(0));
                ValueNode srcLimit = helper.sub(helper.shr(helper.length(value), 1), length);
                helper.intrinsicRangeCheck(srcBegin, Condition.GT, srcLimit);
                ValueNode limit = helper.sub(helper.length(dst), length);
                helper.intrinsicRangeCheck(dstBegin, Condition.GT, limit);
                b.add(new ArrayCopyCallNode(foreignCalls, wordTypes, value, srcBegin, dst, dstBegin, length, JavaKind.Char, JavaKind.Byte, JavaKind.Char, false, true, true, vmConfig.heapWordSize));
            }
            return true;
        }
    });
}
Also used : DynamicNewArrayNode(org.graalvm.compiler.nodes.java.DynamicNewArrayNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) SubNode(org.graalvm.compiler.nodes.calc.SubNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) SnippetSubstitutionInvocationPlugin(org.graalvm.compiler.replacements.SnippetSubstitutionInvocationPlugin) InlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.InlineOnlyInvocationPlugin) ArrayCopyCallNode(org.graalvm.compiler.replacements.arraycopy.ArrayCopyCallNode) ArrayLengthNode(org.graalvm.compiler.nodes.java.ArrayLengthNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) HotSpotInvocationPluginHelper(org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper)

Aggregations

ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)5 HotSpotInvocationPluginHelper (org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper)5 ValueNode (org.graalvm.compiler.nodes.ValueNode)5 GraphBuilderContext (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext)5 InvocationPlugin (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin)5 InlineOnlyInvocationPlugin (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.InlineOnlyInvocationPlugin)5 Receiver (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver)5 Registration (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration)5 SnippetSubstitutionInvocationPlugin (org.graalvm.compiler.replacements.SnippetSubstitutionInvocationPlugin)5 LogicNode (org.graalvm.compiler.nodes.LogicNode)2 DynamicNewArrayNode (org.graalvm.compiler.nodes.java.DynamicNewArrayNode)2 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)1 CurrentJavaThreadNode (org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode)1 HotSpotReflectionGetCallerClassNode (org.graalvm.compiler.hotspot.replacements.HotSpotReflectionGetCallerClassNode)1 HubGetClassNode (org.graalvm.compiler.hotspot.replacements.HubGetClassNode)1 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)1 PiNode (org.graalvm.compiler.nodes.PiNode)1 AndNode (org.graalvm.compiler.nodes.calc.AndNode)1 LeftShiftNode (org.graalvm.compiler.nodes.calc.LeftShiftNode)1 SubNode (org.graalvm.compiler.nodes.calc.SubNode)1