Search in sources :

Example 1 with ObjectEqualsNode

use of org.graalvm.compiler.nodes.calc.ObjectEqualsNode in project graal by oracle.

the class HashMapGetTest method hashMapTest.

@Test
public void hashMapTest() {
    HashMap<Integer, Integer> map = new HashMap<>();
    ResolvedJavaMethod get = getResolvedJavaMethod(HashMapGetTest.class, "mapGet");
    for (int i = 0; i < 5000; i++) {
        mapGet(map, i);
        map.put(i, i);
        mapGet(map, i);
    }
    test(get, null, map, new Integer(0));
    for (IfNode ifNode : lastCompiledGraph.getNodes(IfNode.TYPE)) {
        LogicNode condition = ifNode.condition();
        if (ifNode.getTrueSuccessorProbability() < 0.4 && condition instanceof ObjectEqualsNode) {
            assertTrue(ifNode.trueSuccessor().next() instanceof ReturnNode, "Expected return.", ifNode.trueSuccessor(), ifNode.trueSuccessor().next());
        }
    }
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) HashMap(java.util.HashMap) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) IfNode(org.graalvm.compiler.nodes.IfNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) Test(org.junit.Test)

Example 2 with ObjectEqualsNode

use of org.graalvm.compiler.nodes.calc.ObjectEqualsNode 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 3 with ObjectEqualsNode

use of org.graalvm.compiler.nodes.calc.ObjectEqualsNode in project graal by oracle.

the class MethodTypeFlowBuilder method apply.

protected void apply() {
    // assert method.getAnnotation(Fold.class) == null : method;
    if (method.getAnnotation(NodeIntrinsic.class) != null) {
        graph.getDebug().log("apply MethodTypeFlow on node intrinsic %s", method);
        AnalysisType returnType = (AnalysisType) method.getSignature().getReturnType(method.getDeclaringClass());
        if (returnType.getJavaKind() == JavaKind.Object) {
            /*
                 * This is a method used in a snippet, so most likely the return value does not
                 * matter at all. However, some methods return an object, and the snippet continues
                 * to work with the object. So pretend that this method returns an object of the
                 * exact return type.
                 */
            TypeFlow<?> returnTypeFlow = methodFlow.getResultFlow().getDeclaredType().getTypeFlow(this.bb, true);
            returnTypeFlow = new ProxyTypeFlow(null, returnTypeFlow);
            FormalReturnTypeFlow resultFlow = new FormalReturnTypeFlow(null, returnType, method);
            returnTypeFlow.addOriginalUse(this.bb, resultFlow);
            methodFlow.addMiscEntry(returnTypeFlow);
            methodFlow.setResult(resultFlow);
        }
        return;
    }
    if (!parse()) {
        return;
    }
    this.bb.getUnsupportedFeatures().checkMethod(method, graph);
    processedNodes = new NodeBitMap(graph);
    TypeFlowsOfNodes typeFlows = new TypeFlowsOfNodes();
    for (Node n : graph.getNodes()) {
        if (n instanceof ParameterNode) {
            ParameterNode node = (ParameterNode) n;
            if (node.getStackKind() == JavaKind.Object) {
                TypeFlowBuilder<?> paramBuilder = TypeFlowBuilder.create(bb, node, FormalParamTypeFlow.class, () -> {
                    boolean isStatic = Modifier.isStatic(method.getModifiers());
                    int index = node.index();
                    FormalParamTypeFlow parameter;
                    if (!isStatic && index == 0) {
                        AnalysisType paramType = method.getDeclaringClass();
                        parameter = new FormalReceiverTypeFlow(node, paramType, method);
                    } else {
                        int offset = isStatic ? 0 : 1;
                        AnalysisType paramType = (AnalysisType) method.getSignature().getParameterType(index - offset, method.getDeclaringClass());
                        parameter = new FormalParamTypeFlow(node, paramType, method, index);
                    }
                    methodFlow.setParameter(index, parameter);
                    return parameter;
                });
                typeFlowGraphBuilder.checkFormalParameterBuilder(paramBuilder);
                typeFlows.add(node, paramBuilder);
            }
        } else if (n instanceof BoxNode) {
            BoxNode node = (BoxNode) n;
            Object key = uniqueKey(node);
            BytecodeLocation boxSite = bb.analysisPolicy().createAllocationSite(bb, key, methodFlow.getMethod());
            AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
            TypeFlowBuilder<?> boxBuilder = TypeFlowBuilder.create(bb, node, BoxTypeFlow.class, () -> {
                BoxTypeFlow boxFlow = new BoxTypeFlow(node, type, boxSite);
                methodFlow.addAllocation(boxFlow);
                return boxFlow;
            });
            typeFlows.add(node, boxBuilder);
        }
        for (Node input : n.inputs()) {
            /*
                 * TODO change the handling of constants so that the SourceTypeFlow is created on
                 * demand, with the optimization that only one SourceTypeFlow is created ever for
                 * every distinct object (using, e.g., caching in a global IdentityHashMap).
                 */
            if (input instanceof ConstantNode && !typeFlows.contains((ConstantNode) input)) {
                ConstantNode node = (ConstantNode) input;
                if (node.asJavaConstant().isNull()) {
                    TypeFlowBuilder<SourceTypeFlow> sourceBuilder = TypeFlowBuilder.create(bb, node, SourceTypeFlow.class, () -> {
                        SourceTypeFlow constantSource = new SourceTypeFlow(node, TypeState.forNull());
                        methodFlow.addSource(constantSource);
                        return constantSource;
                    });
                    typeFlows.add(node, sourceBuilder);
                } else if (node.asJavaConstant().getJavaKind() == JavaKind.Object) {
                    /*
                         * TODO a SubstrateObjectConstant wrapping a PrimitiveConstant has kind
                         * equals to Object. Do we care about the effective value of these primitive
                         * constants in the analysis?
                         */
                    assert StampTool.isExactType(node);
                    AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
                    assert type.isInstantiated();
                    TypeFlowBuilder<SourceTypeFlow> sourceBuilder = TypeFlowBuilder.create(bb, node, SourceTypeFlow.class, () -> {
                        SourceTypeFlow constantSource = new SourceTypeFlow(node, TypeState.forConstant(this.bb, node.asJavaConstant(), type));
                        methodFlow.addSource(constantSource);
                        return constantSource;
                    });
                    typeFlows.add(node, sourceBuilder);
                }
            }
        }
    }
    // Propagate the type flows through the method's graph
    new NodeIterator(graph.start(), typeFlows).apply();
    /* Prune the method graph. Eliminate nodes with no uses. */
    typeFlowGraphBuilder.build();
    /*
         * Make sure that all existing InstanceOfNodes are registered even when only used as an
         * input of a conditional.
         */
    for (Node n : graph.getNodes()) {
        if (n instanceof InstanceOfNode) {
            InstanceOfNode instanceOf = (InstanceOfNode) n;
            markFieldsUsedInComparison(instanceOf.getValue());
        } else if (n instanceof ObjectEqualsNode) {
            ObjectEqualsNode compareNode = (ObjectEqualsNode) n;
            markFieldsUsedInComparison(compareNode.getX());
            markFieldsUsedInComparison(compareNode.getY());
        }
    }
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) TypeFlowBuilder(com.oracle.graal.pointsto.flow.builder.TypeFlowBuilder) 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) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) BytecodeLocation(com.oracle.graal.pointsto.flow.context.BytecodeLocation) NodeIntrinsic(org.graalvm.compiler.graph.Node.NodeIntrinsic) PostOrderNodeIterator(org.graalvm.compiler.phases.graph.PostOrderNodeIterator) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode)

Example 4 with ObjectEqualsNode

use of org.graalvm.compiler.nodes.calc.ObjectEqualsNode in project graal by oracle.

the class IfNode method tryEliminateBoxedReferenceEquals.

/**
 * Attempts to replace the following pattern:
 *
 * <pre>
 * Integer x = ...;
 * Integer y = ...;
 * if ((x == y) || x.equals(y)) { ... }
 * </pre>
 *
 * with:
 *
 * <pre>
 * Integer x = ...;
 * Integer y = ...;
 * if (x.equals(y)) { ... }
 * </pre>
 *
 * whenever the probability that the reference check will pass is relatively small.
 *
 * See GR-1315 for more information.
 */
private boolean tryEliminateBoxedReferenceEquals(SimplifierTool tool) {
    if (!(condition instanceof ObjectEqualsNode)) {
        return false;
    }
    MetaAccessProvider meta = tool.getMetaAccess();
    ObjectEqualsNode equalsCondition = (ObjectEqualsNode) condition;
    ValueNode x = equalsCondition.getX();
    ValueNode y = equalsCondition.getY();
    ResolvedJavaType integerType = meta.lookupJavaType(Integer.class);
    // At least one argument for reference equal must be a boxed primitive.
    NodeView view = NodeView.from(tool);
    if (!x.stamp(view).javaType(meta).equals(integerType) && !y.stamp(view).javaType(meta).equals(integerType)) {
        return false;
    }
    // no sense to eliminate it.
    if (getTrueSuccessorProbability() > 0.4) {
        return false;
    }
    // True branch must be empty.
    if (trueSuccessor instanceof BeginNode || trueSuccessor instanceof LoopExitNode) {
        if (trueSuccessor.next() instanceof EndNode) {
        // Empty true branch.
        } else {
            return false;
        }
    } else {
        return false;
    }
    // False branch must only check the unboxed values.
    UnboxNode unbox = null;
    FixedGuardNode unboxCheck = null;
    for (FixedNode node : falseSuccessor.getBlockNodes()) {
        if (!(node instanceof BeginNode || node instanceof UnboxNode || node instanceof FixedGuardNode || node instanceof EndNode || node instanceof LoadFieldNode || node instanceof LoopExitNode)) {
            return false;
        }
        if (node instanceof UnboxNode) {
            if (unbox == null) {
                unbox = (UnboxNode) node;
            } else {
                return false;
            }
        }
        if (!(node instanceof FixedGuardNode)) {
            continue;
        }
        FixedGuardNode fixed = (FixedGuardNode) node;
        if (!(fixed.condition() instanceof IntegerEqualsNode)) {
            continue;
        }
        IntegerEqualsNode equals = (IntegerEqualsNode) fixed.condition();
        if ((isUnboxedFrom(meta, view, equals.getX(), x) && isUnboxedFrom(meta, view, equals.getY(), y)) || (isUnboxedFrom(meta, view, equals.getX(), y) && isUnboxedFrom(meta, view, equals.getY(), x))) {
            unboxCheck = fixed;
        }
    }
    if (unbox == null || unboxCheck == null) {
        return false;
    }
    // Falsify the reference check.
    setCondition(graph().addOrUniqueWithInputs(LogicConstantNode.contradiction()));
    return true;
}
Also used : IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) UnboxNode(org.graalvm.compiler.nodes.extended.UnboxNode) MetaAccessProvider(jdk.vm.ci.meta.MetaAccessProvider)

Example 5 with ObjectEqualsNode

use of org.graalvm.compiler.nodes.calc.ObjectEqualsNode in project graal by oracle.

the class VerifyUsageWithEquals method verify.

@Override
protected boolean verify(StructuredGraph graph, PhaseContext context) {
    for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) {
        // bail out if we compare an object of type klass with == or != (except null checks)
        ResolvedJavaMethod method = graph.method();
        ResolvedJavaType restrictedType = context.getMetaAccess().lookupJavaType(restrictedClass);
        if (method.getDeclaringClass().equals(restrictedType)) {
        // Allow violation in methods of the restricted type itself.
        } else if (isIllegalUsage(method, cn.getX(), cn.getY(), context.getMetaAccess()) || isIllegalUsage(method, cn.getY(), cn.getX(), context.getMetaAccess())) {
            throw new VerificationError("Verification of " + restrictedClass.getName() + " usage failed: Comparing " + cn.getX() + " and " + cn.getY() + " in " + method + " must use .equals() for object equality, not '==' or '!='");
        }
    }
    return true;
}
Also used : ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Aggregations

ObjectEqualsNode (org.graalvm.compiler.nodes.calc.ObjectEqualsNode)5 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)3 MetaAccessProvider (jdk.vm.ci.meta.MetaAccessProvider)2 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)2 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)2 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)2 IfNode (org.graalvm.compiler.nodes.IfNode)2 ValueNode (org.graalvm.compiler.nodes.ValueNode)2 LoadFieldNode (org.graalvm.compiler.nodes.java.LoadFieldNode)2 NewInstanceNode (org.graalvm.compiler.nodes.java.NewInstanceNode)2 TypeFlowBuilder (com.oracle.graal.pointsto.flow.builder.TypeFlowBuilder)1 BytecodeLocation (com.oracle.graal.pointsto.flow.context.BytecodeLocation)1 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)1 AnalysisArraysCopyOfNode (com.oracle.graal.pointsto.nodes.AnalysisArraysCopyOfNode)1 AnalysisUnsafePartitionLoadNode (com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionLoadNode)1 AnalysisUnsafePartitionStoreNode (com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionStoreNode)1 ConvertUnknownValueNode (com.oracle.graal.pointsto.nodes.ConvertUnknownValueNode)1 CInterfaceReadNode (com.oracle.svm.core.graal.nodes.CInterfaceReadNode)1 VaListNextArgNode (com.oracle.svm.core.graal.nodes.VaListNextArgNode)1 StructFieldInfo (com.oracle.svm.hosted.c.info.StructFieldInfo)1