Search in sources :

Example 1 with TypeReference

use of org.graalvm.compiler.core.common.type.TypeReference in project graal by oracle.

the class MethodCallTargetNode method simplify.

@Override
public void simplify(SimplifierTool tool) {
    // attempt to devirtualize the call
    if (invoke().getContextMethod() == null) {
        // avoid invokes that have placeholder bcis: they do not have a valid contextType
        assert (invoke().stateAfter() != null && BytecodeFrame.isPlaceholderBci(invoke().stateAfter().bci)) || BytecodeFrame.isPlaceholderBci(invoke().stateDuring().bci);
        return;
    }
    ResolvedJavaType contextType = (invoke().stateAfter() == null && invoke().stateDuring() == null) ? null : invoke().getContextType();
    ResolvedJavaMethod specialCallTarget = findSpecialCallTarget(invokeKind, receiver(), targetMethod, contextType);
    if (specialCallTarget != null) {
        this.setTargetMethod(specialCallTarget);
        setInvokeKind(InvokeKind.Special);
        return;
    }
    Assumptions assumptions = graph().getAssumptions();
    /*
         * Even though we are not registering an assumption (see comment below), the optimization is
         * only valid when speculative optimizations are enabled.
         */
    if (invokeKind().isIndirect() && invokeKind().isInterface() && assumptions != null) {
        // check if the type of the receiver can narrow the result
        ValueNode receiver = receiver();
        // try to turn a interface call into a virtual call
        ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass();
        /*
             * We need to check the invoke kind to avoid recursive simplification for virtual
             * interface methods calls.
             */
        if (declaredReceiverType.isInterface()) {
            ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor();
            if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) {
                TypeReference speculatedType = TypeReference.createTrusted(assumptions, singleImplementor);
                if (tryCheckCastSingleImplementor(receiver, speculatedType)) {
                    return;
                }
            }
        }
        if (receiver instanceof UncheckedInterfaceProvider) {
            UncheckedInterfaceProvider uncheckedInterfaceProvider = (UncheckedInterfaceProvider) receiver;
            Stamp uncheckedStamp = uncheckedInterfaceProvider.uncheckedStamp();
            if (uncheckedStamp != null) {
                TypeReference speculatedType = StampTool.typeReferenceOrNull(uncheckedStamp);
                if (speculatedType != null) {
                    tryCheckCastSingleImplementor(receiver, speculatedType);
                }
            }
        }
    }
}
Also used : Stamp(org.graalvm.compiler.core.common.type.Stamp) Assumptions(jdk.vm.ci.meta.Assumptions) ValueNode(org.graalvm.compiler.nodes.ValueNode) UncheckedInterfaceProvider(org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 2 with TypeReference

use of org.graalvm.compiler.core.common.type.TypeReference in project graal by oracle.

the class MethodHandleNode method maybeCastArgument.

/**
 * Inserts a node to cast the argument at index to the given type if the given type is more
 * concrete than the argument type.
 *
 * @param adder
 * @param index of the argument to be cast
 * @param type the type the argument should be cast to
 */
private static void maybeCastArgument(GraphAdder adder, ValueNode[] arguments, int index, JavaType type) {
    ValueNode argument = arguments[index];
    if (type instanceof ResolvedJavaType && !((ResolvedJavaType) type).isJavaLangObject()) {
        Assumptions assumptions = adder.getAssumptions();
        TypeReference targetType = TypeReference.create(assumptions, (ResolvedJavaType) type);
        /*
             * When an argument is a Word type, we can have a mismatch of primitive/object types
             * here. Not inserting a PiNode is a safe fallback, and Word types need no additional
             * type information anyway.
             */
        if (targetType != null && !targetType.getType().isPrimitive() && !argument.getStackKind().isPrimitive()) {
            ResolvedJavaType argumentType = StampTool.typeOrNull(argument.stamp(NodeView.DEFAULT));
            if (argumentType == null || (argumentType.isAssignableFrom(targetType.getType()) && !argumentType.equals(targetType.getType()))) {
                LogicNode inst = InstanceOfNode.createAllowNull(targetType, argument, null, null);
                assert !inst.isAlive();
                if (!inst.isTautology()) {
                    inst = adder.add(inst);
                    AnchoringNode guardAnchor = adder.getGuardAnchor();
                    DeoptimizationReason reason = DeoptimizationReason.ClassCastException;
                    DeoptimizationAction action = DeoptimizationAction.InvalidateRecompile;
                    JavaConstant speculation = JavaConstant.NULL_POINTER;
                    GuardingNode guard;
                    if (guardAnchor == null) {
                        FixedGuardNode fixedGuard = adder.add(new FixedGuardNode(inst, reason, action, speculation, false));
                        guard = fixedGuard;
                    } else {
                        GuardNode newGuard = adder.add(new GuardNode(inst, guardAnchor, reason, action, false, speculation));
                        adder.add(new ValueAnchorNode(newGuard));
                        guard = newGuard;
                    }
                    ValueNode valueNode = adder.add(PiNode.create(argument, StampFactory.object(targetType), guard.asNode()));
                    arguments[index] = valueNode;
                }
            }
        }
    }
}
Also used : GuardNode(org.graalvm.compiler.nodes.GuardNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) AnchoringNode(org.graalvm.compiler.nodes.extended.AnchoringNode) JavaConstant(jdk.vm.ci.meta.JavaConstant) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Assumptions(jdk.vm.ci.meta.Assumptions) ValueAnchorNode(org.graalvm.compiler.nodes.extended.ValueAnchorNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) DeoptimizationAction(jdk.vm.ci.meta.DeoptimizationAction) DeoptimizationReason(jdk.vm.ci.meta.DeoptimizationReason) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode)

Example 3 with TypeReference

use of org.graalvm.compiler.core.common.type.TypeReference in project graal by oracle.

the class BytecodeParser method emitCheckForInvokeSuperSpecial.

/**
 * Checks that the class of the receiver of an {@link Bytecodes#INVOKESPECIAL} in a method
 * declared in an interface (i.e., a default method) is assignable to the interface. If not,
 * then deoptimize so that the interpreter can throw an {@link IllegalAccessError}.
 *
 * This is a check not performed by the verifier and so must be performed at runtime.
 *
 * @param args arguments to an {@link Bytecodes#INVOKESPECIAL} implementing a direct call to a
 *            method in a super class
 */
protected void emitCheckForInvokeSuperSpecial(ValueNode[] args) {
    ResolvedJavaType callingClass = method.getDeclaringClass();
    if (callingClass.getHostClass() != null) {
        callingClass = callingClass.getHostClass();
    }
    if (callingClass.isInterface()) {
        ValueNode receiver = args[0];
        TypeReference checkedType = TypeReference.createTrusted(graph.getAssumptions(), callingClass);
        LogicNode condition = genUnique(createInstanceOf(checkedType, receiver, null));
        FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, ClassCastException, None, false));
        args[0] = append(PiNode.create(receiver, StampFactory.object(checkedType, true), fixedGuard));
    }
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 4 with TypeReference

use of org.graalvm.compiler.core.common.type.TypeReference in project graal by oracle.

the class DefaultJavaLoweringProvider method lowerStoreIndexedNode.

protected void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool) {
    StructuredGraph graph = storeIndexed.graph();
    ValueNode value = storeIndexed.value();
    ValueNode array = storeIndexed.array();
    array = this.createNullCheckedValue(array, storeIndexed, tool);
    GuardingNode boundsCheck = getBoundsCheck(storeIndexed, array, tool);
    JavaKind elementKind = storeIndexed.elementKind();
    LogicNode condition = null;
    if (elementKind == JavaKind.Object && !StampTool.isPointerAlwaysNull(value)) {
        /* Array store check. */
        TypeReference arrayType = StampTool.typeReferenceOrNull(array);
        if (arrayType != null && arrayType.isExact()) {
            ResolvedJavaType elementType = arrayType.getType().getComponentType();
            if (!elementType.isJavaLangObject()) {
                TypeReference typeReference = TypeReference.createTrusted(storeIndexed.graph().getAssumptions(), elementType);
                LogicNode typeTest = graph.addOrUniqueWithInputs(InstanceOfNode.create(typeReference, value));
                condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, GraalDirectives.UNLIKELY_PROBABILITY);
            }
        } else {
            /*
                 * The guard on the read hub should be the null check of the array that was
                 * introduced earlier.
                 */
            ValueNode arrayClass = createReadHub(graph, array, tool);
            ValueNode componentHub = createReadArrayComponentHub(graph, arrayClass, storeIndexed);
            LogicNode typeTest = graph.unique(InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), componentHub, value, false));
            condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, GraalDirectives.UNLIKELY_PROBABILITY);
        }
    }
    AddressNode address = createArrayIndexAddress(graph, array, elementKind, storeIndexed.index(), boundsCheck);
    WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value), arrayStoreBarrierType(storeIndexed.elementKind())));
    memoryWrite.setGuard(boundsCheck);
    if (condition != null) {
        tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
    }
    memoryWrite.setStateAfter(storeIndexed.stateAfter());
    graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
}
Also used : StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) AtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode) JavaWriteNode(org.graalvm.compiler.nodes.extended.JavaWriteNode) LoweredAtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 5 with TypeReference

use of org.graalvm.compiler.core.common.type.TypeReference in project graal by oracle.

the class DynamicPiNode method findSynonym.

private static ValueNode findSynonym(Assumptions assumptions, ConstantReflectionProvider constantReflection, ValueNode object, GuardingNode guard, ValueNode typeMirror, boolean exact) {
    if (typeMirror.isConstant()) {
        ResolvedJavaType t = constantReflection.asJavaType(typeMirror.asConstant());
        if (t != null) {
            Stamp staticPiStamp;
            if (t.isPrimitive()) {
                staticPiStamp = StampFactory.alwaysNull();
            } else {
                TypeReference type = exact ? TypeReference.createExactTrusted(t) : TypeReference.createTrusted(assumptions, t);
                staticPiStamp = StampFactory.object(type);
            }
            return PiNode.create(object, staticPiStamp, (ValueNode) guard);
        }
    }
    return null;
}
Also used : Stamp(org.graalvm.compiler.core.common.type.Stamp) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Aggregations

TypeReference (org.graalvm.compiler.core.common.type.TypeReference)21 ValueNode (org.graalvm.compiler.nodes.ValueNode)15 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)13 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)8 LogicNode (org.graalvm.compiler.nodes.LogicNode)8 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)6 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)6 Assumptions (jdk.vm.ci.meta.Assumptions)4 JavaType (jdk.vm.ci.meta.JavaType)4 Stamp (org.graalvm.compiler.core.common.type.Stamp)4 PiNode (org.graalvm.compiler.nodes.PiNode)4 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)4 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)3 HostedType (com.oracle.svm.hosted.meta.HostedType)2 RuntimeConstraint (jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)2 JavaConstant (jdk.vm.ci.meta.JavaConstant)2 JavaKind (jdk.vm.ci.meta.JavaKind)2 JavaTypeProfile (jdk.vm.ci.meta.JavaTypeProfile)2 Signature (jdk.vm.ci.meta.Signature)2 AbstractObjectStamp (org.graalvm.compiler.core.common.type.AbstractObjectStamp)2