Search in sources :

Example 1 with JavaTypeProfile

use of jdk.vm.ci.meta.JavaTypeProfile in project graal by oracle.

the class StaticAnalysisResultsBuilder method cachedTypeProfile.

private JavaTypeProfile cachedTypeProfile(JavaTypeProfile[] cache, int cacheIdx, TypeState typeState) {
    JavaTypeProfile result = cache[cacheIdx];
    if (result == null) {
        result = createTypeProfile(typeState);
        cache[cacheIdx] = result;
    }
    return result;
}
Also used : JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile)

Example 2 with JavaTypeProfile

use of jdk.vm.ci.meta.JavaTypeProfile in project graal by oracle.

the class BytecodeParser method adjustProfileForInvocationPlugin.

/**
 * Adjusts the profile for an indirect invocation of a virtual method for which there is an
 * intrinsic. The adjustment made by this method is to remove all types from the profile that do
 * not override {@code targetMethod}.
 *
 * @param profile the profile to adjust
 * @param targetMethod the virtual method for which there is an intrinsic
 * @return the adjusted profile or the original {@code profile} object if no adjustment was made
 */
protected JavaTypeProfile adjustProfileForInvocationPlugin(JavaTypeProfile profile, ResolvedJavaMethod targetMethod) {
    if (profile.getTypes().length > 0) {
        List<ProfiledType> retained = new ArrayList<>();
        double notRecordedProbability = profile.getNotRecordedProbability();
        for (ProfiledType ptype : profile.getTypes()) {
            if (!ptype.getType().resolveMethod(targetMethod, method.getDeclaringClass()).equals(targetMethod)) {
                retained.add(ptype);
            } else {
                notRecordedProbability += ptype.getProbability();
            }
        }
        if (!retained.isEmpty()) {
            if (retained.size() != profile.getTypes().length) {
                return new JavaTypeProfile(profile.getNullSeen(), notRecordedProbability, retained.toArray(new ProfiledType[retained.size()]));
            }
        } else {
            return new JavaTypeProfile(profile.getNullSeen(), notRecordedProbability, new ProfiledType[0]);
        }
    }
    return profile;
}
Also used : ProfiledType(jdk.vm.ci.meta.JavaTypeProfile.ProfiledType) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ArrayList(java.util.ArrayList)

Example 3 with JavaTypeProfile

use of jdk.vm.ci.meta.JavaTypeProfile in project graal by oracle.

the class AssertTypeStateNode method alwaysHolds.

@Override
protected boolean alwaysHolds(boolean reportError) {
    if (getInput().isConstant()) {
        if (getInput().asJavaConstant().isNull()) {
            if (typeState.getNullSeen() == TriState.FALSE) {
                if (reportError) {
                    throw shouldNotReachHere("Null constant not compatible with type state: " + this + " : " + getTypeState());
                }
            } else {
                return true;
            }
        } else {
            Set<ResolvedJavaType> ourTypes = new HashSet<>();
            addAllTypes(ourTypes, typeState);
            if (!ourTypes.contains(StampTool.typeOrNull(getInput()))) {
                if (reportError) {
                    throw shouldNotReachHere("Constant object not compatible with type state: " + this + " : " + getTypeState() + ", " + StampTool.typeOrNull(getInput()));
                }
            } else {
                return true;
            }
        }
    }
    if (getInput() instanceof AssertTypeStateNode) {
        JavaTypeProfile inputTypeState = ((AssertTypeStateNode) getInput()).getTypeState();
        Set<ResolvedJavaType> inputTypes = new HashSet<>();
        addAllTypes(inputTypes, inputTypeState);
        Set<ResolvedJavaType> ourTypes = new HashSet<>();
        addAllTypes(ourTypes, typeState);
        if (ourTypes.containsAll(inputTypes)) {
            /* Another node is already checking the same or a stronger type state. */
            return true;
        }
    }
    return false;
}
Also used : JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) HashSet(java.util.HashSet)

Example 4 with JavaTypeProfile

use of jdk.vm.ci.meta.JavaTypeProfile 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 JavaTypeProfile

use of jdk.vm.ci.meta.JavaTypeProfile in project graal by oracle.

the class BytecodeParser method genInstanceOf.

private void genInstanceOf() {
    int cpi = getStream().readCPI();
    JavaType type = lookupType(cpi, INSTANCEOF);
    ValueNode object = frameState.pop(JavaKind.Object);
    if (!(type instanceof ResolvedJavaType)) {
        handleUnresolvedInstanceOf(type, object);
        return;
    }
    TypeReference resolvedType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) type);
    JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
    for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
        if (plugin.handleInstanceOf(this, object, resolvedType.getType(), profile)) {
            return;
        }
    }
    LogicNode instanceOfNode = null;
    if (profile != null) {
        if (profile.getNullSeen().isFalse()) {
            object = nullCheckedValue(object);
            ResolvedJavaType singleType = profile.asSingleType();
            if (singleType != null) {
                LogicNode typeCheck = append(createInstanceOf(TypeReference.createExactTrusted(singleType), object, profile));
                if (!typeCheck.isTautology()) {
                    append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
                }
                instanceOfNode = LogicConstantNode.forBoolean(resolvedType.getType().isAssignableFrom(singleType));
            }
        }
    }
    if (instanceOfNode == null) {
        instanceOfNode = createInstanceOf(resolvedType, object, null);
    }
    LogicNode logicNode = genUnique(instanceOfNode);
    int next = getStream().nextBCI();
    int value = getStream().readUByte(next);
    if (next <= currentBlock.endBci && (value == Bytecodes.IFEQ || value == Bytecodes.IFNE)) {
        getStream().next();
        BciBlock firstSucc = currentBlock.getSuccessor(0);
        BciBlock secondSucc = currentBlock.getSuccessor(1);
        if (firstSucc != secondSucc) {
            boolean negate = value != Bytecodes.IFNE;
            if (negate) {
                BciBlock tmp = firstSucc;
                firstSucc = secondSucc;
                secondSucc = tmp;
            }
            genIf(instanceOfNode, firstSucc, secondSucc, getProfileProbability(negate));
        } else {
            appendGoto(firstSucc);
        }
    } else {
        // Most frequent for value is IRETURN, followed by ISTORE.
        frameState.push(JavaKind.Int, append(genConditional(logicNode)));
    }
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) NodePlugin(org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Aggregations

JavaTypeProfile (jdk.vm.ci.meta.JavaTypeProfile)11 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)7 ArrayList (java.util.ArrayList)3 RuntimeConstraint (jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)3 JavaType (jdk.vm.ci.meta.JavaType)3 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)3 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)3 LogicNode (org.graalvm.compiler.nodes.LogicNode)3 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)2 TypeReference (org.graalvm.compiler.core.common.type.TypeReference)2 NodePlugin (org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin)2 InstanceOfTypeFlow (com.oracle.graal.pointsto.flow.InstanceOfTypeFlow)1 InvokeTypeFlow (com.oracle.graal.pointsto.flow.InvokeTypeFlow)1 MethodFlowsGraph (com.oracle.graal.pointsto.flow.MethodFlowsGraph)1 MethodTypeFlow (com.oracle.graal.pointsto.flow.MethodTypeFlow)1 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)1 BytecodeEntry (com.oracle.graal.pointsto.results.StaticAnalysisResults.BytecodeEntry)1 TypeState (com.oracle.graal.pointsto.typestate.TypeState)1 HashSet (java.util.HashSet)1