Search in sources :

Example 1 with LoadHubNode

use of org.graalvm.compiler.nodes.extended.LoadHubNode in project graal by oracle.

the class MultiTypeGuardInlineInfo method createDispatchOnTypeBeforeInvoke.

private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, StampProvider stampProvider, ConstantReflectionProvider constantReflection) {
    assert ptypes.size() >= 1;
    ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
    LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
    graph.getDebug().log("Type switch with %d types", concretes.size());
    ResolvedJavaType[] keys = new ResolvedJavaType[ptypes.size()];
    double[] keyProbabilities = new double[ptypes.size() + 1];
    int[] keySuccessors = new int[ptypes.size() + 1];
    double totalProbability = notRecordedTypeProbability;
    for (int i = 0; i < ptypes.size(); i++) {
        keys[i] = ptypes.get(i).getType();
        keyProbabilities[i] = ptypes.get(i).getProbability();
        totalProbability += keyProbabilities[i];
        keySuccessors[i] = invokeIsOnlySuccessor ? 0 : typesToConcretes.get(i);
        assert keySuccessors[i] < successors.length - 1 : "last successor is the unknownTypeSux";
    }
    keyProbabilities[keyProbabilities.length - 1] = notRecordedTypeProbability;
    keySuccessors[keySuccessors.length - 1] = successors.length - 1;
    // Normalize the probabilities.
    for (int i = 0; i < keyProbabilities.length; i++) {
        keyProbabilities[i] /= totalProbability;
    }
    TypeSwitchNode typeSwitch = graph.add(new TypeSwitchNode(hub, successors, keys, keyProbabilities, keySuccessors, constantReflection));
    FixedWithNextNode pred = (FixedWithNextNode) invoke.asNode().predecessor();
    pred.setNext(typeSwitch);
    return false;
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) TypeSwitchNode(org.graalvm.compiler.nodes.java.TypeSwitchNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 2 with LoadHubNode

use of org.graalvm.compiler.nodes.extended.LoadHubNode in project graal by oracle.

the class DefaultHotSpotLoweringProvider method createReadHub.

@Override
protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, LoweringTool tool) {
    if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) {
        return graph.unique(new LoadHubNode(tool.getStampProvider(), object));
    }
    assert !object.isConstant() || object.isNullConstant();
    KlassPointerStamp hubStamp = KlassPointerStamp.klassNonNull();
    if (runtime.getVMConfig().useCompressedClassPointers) {
        hubStamp = hubStamp.compressed(runtime.getVMConfig().getKlassEncoding());
    }
    AddressNode address = createOffsetAddress(graph, object, runtime.getVMConfig().hubOffset);
    LocationIdentity hubLocation = runtime.getVMConfig().useCompressedClassPointers ? COMPRESSED_HUB_LOCATION : HUB_LOCATION;
    FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(address, hubLocation, null, hubStamp, null, BarrierType.NONE));
    if (runtime.getVMConfig().useCompressedClassPointers) {
        return HotSpotCompressionNode.uncompress(memoryRead, runtime.getVMConfig().getKlassEncoding());
    } else {
        return memoryRead;
    }
}
Also used : LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) KlassPointerStamp(org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp) FloatingReadNode(org.graalvm.compiler.nodes.memory.FloatingReadNode) GetObjectAddressNode(org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode) ComputeObjectAddressNode(org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) LocationIdentity(org.graalvm.word.LocationIdentity)

Example 3 with LoadHubNode

use of org.graalvm.compiler.nodes.extended.LoadHubNode in project graal by oracle.

the class SubstrateGraphBuilderPlugins method registerKnownIntrinsicsPlugins.

private static void registerKnownIntrinsicsPlugins(InvocationPlugins plugins, boolean analysis) {
    Registration r = new Registration(plugins, KnownIntrinsics.class);
    r.register0("heapBase", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Object, ReadRegisterFixedNode.forHeapBase());
            return true;
        }
    });
    r.register1("readArrayLength", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode array) {
            b.addPush(JavaKind.Int, new ArrayLengthNode(array));
            return true;
        }
    });
    r.register1("readHub", Object.class, new InvocationPlugin() {

        @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.register3("formatObject", Pointer.class, Class.class, boolean.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode memory, ValueNode hub, ValueNode rememberedSet) {
            b.addPush(JavaKind.Object, new FormatObjectNode(memory, hub, rememberedSet));
            return true;
        }
    });
    r.register5("formatArray", Pointer.class, Class.class, int.class, boolean.class, boolean.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode memory, ValueNode hub, ValueNode length, ValueNode rememberedSet, ValueNode unaligned) {
            b.addPush(JavaKind.Object, new FormatArrayNode(memory, hub, length, rememberedSet, unaligned));
            return true;
        }
    });
    r.register2("unsafeCast", Object.class, Class.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode toTypeNode) {
            /*
                 * We need to make sure that the updated type information does not flow up, because
                 * it can depend on any condition before (and we do not know which condition, so we
                 * cannot anchor at a particular block).
                 */
            ResolvedJavaType toType = typeValue(b.getConstantReflection(), b, targetMethod, toTypeNode, "toType");
            TypeReference toTypeRef = TypeReference.createTrustedWithoutAssumptions(toType);
            b.addPush(JavaKind.Object, new FixedValueAnchorNode(object, StampFactory.object(toTypeRef)));
            return true;
        }
    });
    r.register1("nonNullPointer", Pointer.class, new InvocationPlugin() {

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

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Object, new ReadStackPointerNode());
            return true;
        }
    });
    r.register1("writeStackPointer", Pointer.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            b.add(new WriteStackPointerNode(value));
            return true;
        }
    });
    r.register0("readInstructionPointer", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Object, new ReadInstructionPointerNode());
            return true;
        }
    });
    r.register0("readCallerStackPointer", new InvocationPlugin() {

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

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

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode result, ValueNode sp, ValueNode ip) {
            b.add(new FarReturnNode(result, sp, ip));
            return true;
        }
    });
    r.register0("testDeoptimize", new InvocationPlugin() {

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

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            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;
        }
    });
    r.register2("convertUnknownValue", Object.class, Class.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode typeNode) {
            ResolvedJavaType type = typeValue(b.getConstantReflection(), b, targetMethod, typeNode, "type");
            TypeReference typeRef = TypeReference.createTrustedWithoutAssumptions(type);
            Stamp stamp = StampFactory.object(typeRef);
            if (analysis) {
                b.addPush(JavaKind.Object, new ConvertUnknownValueNode(object, stamp));
            } else {
                b.addPush(JavaKind.Object, PiNode.create(object, stamp));
            }
            return true;
        }
    });
}
Also used : FixedValueAnchorNode(org.graalvm.compiler.nodes.extended.FixedValueAnchorNode) TestDeoptimizeNode(com.oracle.svm.core.graal.nodes.TestDeoptimizeNode) DynamicPiNode(org.graalvm.compiler.nodes.DynamicPiNode) PiNode(org.graalvm.compiler.nodes.PiNode) ConvertUnknownValueNode(com.oracle.graal.pointsto.nodes.ConvertUnknownValueNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) FarReturnNode(com.oracle.svm.core.graal.nodes.FarReturnNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) ReadStackPointerNode(com.oracle.svm.core.graal.nodes.ReadStackPointerNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) ArrayLengthNode(org.graalvm.compiler.nodes.java.ArrayLengthNode) ReadCallerStackPointerNode(com.oracle.svm.core.graal.nodes.ReadCallerStackPointerNode) WriteStackPointerNode(com.oracle.svm.core.graal.nodes.WriteStackPointerNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) ReadInstructionPointerNode(com.oracle.svm.core.graal.nodes.ReadInstructionPointerNode) ReadReturnAddressNode(com.oracle.svm.core.graal.nodes.ReadReturnAddressNode) FormatObjectNode(com.oracle.svm.core.graal.nodes.FormatObjectNode) FormatArrayNode(com.oracle.svm.core.graal.nodes.FormatArrayNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) StackValueNode(com.oracle.svm.core.graal.stackvalue.StackValueNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ConvertUnknownValueNode(com.oracle.graal.pointsto.nodes.ConvertUnknownValueNode) SharedMethod(com.oracle.svm.core.meta.SharedMethod) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 4 with LoadHubNode

use of org.graalvm.compiler.nodes.extended.LoadHubNode in project graal by oracle.

the class BytecodeParser method guardIntrinsic.

/**
 * Weaves a test of the receiver type to ensure the dispatch will select {@code targetMethod}
 * and not another method that overrides it. This should only be called if there is an intrinsic
 * (i.e., an {@link InvocationPlugin}) for {@code targetMethod} and the invocation is indirect.
 *
 * The control flow woven around the intrinsic is as follows:
 *
 * <pre>
 *  if (LoadMethod(LoadHub(receiver)) == targetMethod) {
 *       <intrinsic for targetMethod>
 *  } else {
 *       <virtual call to targetMethod>
 *  }
 * </pre>
 *
 * The {@code else} branch is woven by {@link #afterInvocationPluginExecution}.
 *
 * @return {@code null} if the intrinsic cannot be used otherwise an object to be used by
 *         {@link #afterInvocationPluginExecution} to weave code for the non-intrinsic branch
 */
protected IntrinsicGuard guardIntrinsic(ValueNode[] args, ResolvedJavaMethod targetMethod, InvocationPluginReceiver pluginReceiver) {
    ValueNode intrinsicReceiver = args[0];
    ResolvedJavaType receiverType = StampTool.typeOrNull(intrinsicReceiver);
    if (receiverType == null) {
        // The verifier guarantees it to be at least type declaring targetMethod
        receiverType = targetMethod.getDeclaringClass();
    }
    ResolvedJavaMethod resolvedMethod = receiverType.resolveMethod(targetMethod, method.getDeclaringClass());
    if (resolvedMethod == null || resolvedMethod.equals(targetMethod)) {
        assert resolvedMethod == null || targetMethod.getDeclaringClass().isAssignableFrom(resolvedMethod.getDeclaringClass());
        Mark mark = graph.getMark();
        FixedWithNextNode currentLastInstr = lastInstr;
        ValueNode nonNullReceiver = pluginReceiver.get();
        Stamp methodStamp = stampProvider.createMethodStamp();
        LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
        LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
        ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
        LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
        JavaTypeProfile profile = null;
        if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
            profile = profilingInfo.getTypeProfile(bci());
            if (profile != null) {
                JavaTypeProfile newProfile = adjustProfileForInvocationPlugin(profile, targetMethod);
                if (newProfile != profile) {
                    if (newProfile.getTypes().length == 0) {
                        // All profiled types select the intrinsic so
                        // emit a fixed guard instead of an if-then-else.
                        lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
                        return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
                    }
                } else {
                    // No profiled types select the intrinsic so emit a virtual call
                    return null;
                }
                profile = newProfile;
            }
        }
        AbstractBeginNode intrinsicBranch = graph.add(new BeginNode());
        AbstractBeginNode nonIntrinsicBranch = graph.add(new BeginNode());
        append(new IfNode(compare, intrinsicBranch, nonIntrinsicBranch, FAST_PATH_PROBABILITY));
        lastInstr = intrinsicBranch;
        return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, nonIntrinsicBranch, profile);
    } else {
        // Receiver selects an overriding method so emit a virtual call
        return null;
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) Mark(org.graalvm.compiler.graph.Graph.Mark) IfNode(org.graalvm.compiler.nodes.IfNode) LoadMethodNode(org.graalvm.compiler.nodes.extended.LoadMethodNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 5 with LoadHubNode

use of org.graalvm.compiler.nodes.extended.LoadHubNode in project graal by oracle.

the class SubstrateBasicLoweringProvider method createReadHub.

@Override
protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, LoweringTool tool) {
    if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) {
        return graph.unique(new LoadHubNode(tool.getStampProvider(), object));
    }
    assert !object.isConstant() || object.asJavaConstant().isNull();
    ValueNode memoryRead = createReadBaseWithOffset(graph, object, getObjectLayout().getHubOffset(), FrameAccess.getWordStamp());
    ValueNode masked = graph.unique(new AndNode(memoryRead, ConstantNode.forIntegerKind(FrameAccess.getWordKind(), ObjectHeader.BITS_CLEAR.rawValue(), graph)));
    return uncompress(graph.unique(new FloatingWordCastNode(dynamicHubStamp, masked)));
}
Also used : LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) FloatingWordCastNode(com.oracle.svm.core.graal.nodes.FloatingWordCastNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) AndNode(org.graalvm.compiler.nodes.calc.AndNode)

Aggregations

LoadHubNode (org.graalvm.compiler.nodes.extended.LoadHubNode)10 ValueNode (org.graalvm.compiler.nodes.ValueNode)5 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)4 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)4 Stamp (org.graalvm.compiler.core.common.type.Stamp)4 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)3 Constant (jdk.vm.ci.meta.Constant)2 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)2 IntegerStamp (org.graalvm.compiler.core.common.type.IntegerStamp)2 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)2 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)2 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)2 LogicNode (org.graalvm.compiler.nodes.LogicNode)2 ConvertUnknownValueNode (com.oracle.graal.pointsto.nodes.ConvertUnknownValueNode)1 FarReturnNode (com.oracle.svm.core.graal.nodes.FarReturnNode)1 FloatingWordCastNode (com.oracle.svm.core.graal.nodes.FloatingWordCastNode)1 FormatArrayNode (com.oracle.svm.core.graal.nodes.FormatArrayNode)1 FormatObjectNode (com.oracle.svm.core.graal.nodes.FormatObjectNode)1 ReadCallerStackPointerNode (com.oracle.svm.core.graal.nodes.ReadCallerStackPointerNode)1 ReadInstructionPointerNode (com.oracle.svm.core.graal.nodes.ReadInstructionPointerNode)1