Search in sources :

Example 6 with JavaTypeProfile

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

the class BytecodeParser method genCheckCast.

private void genCheckCast() {
    int cpi = getStream().readCPI();
    JavaType type = lookupType(cpi, CHECKCAST);
    ValueNode object = frameState.pop(JavaKind.Object);
    if (!(type instanceof ResolvedJavaType)) {
        handleUnresolvedCheckCast(type, object);
        return;
    }
    TypeReference checkedType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) type);
    JavaTypeProfile profile = getProfileForTypeCheck(checkedType);
    for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
        if (plugin.handleCheckCast(this, object, checkedType.getType(), profile)) {
            return;
        }
    }
    ValueNode castNode = null;
    if (profile != null) {
        if (profile.getNullSeen().isFalse()) {
            object = nullCheckedValue(object);
            ResolvedJavaType singleType = profile.asSingleType();
            if (singleType != null && checkedType.getType().isAssignableFrom(singleType)) {
                LogicNode typeCheck = append(createInstanceOf(TypeReference.createExactTrusted(singleType), object, profile));
                if (typeCheck.isTautology()) {
                    castNode = object;
                } else {
                    FixedGuardNode fixedGuard = append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile, false));
                    castNode = append(PiNode.create(object, StampFactory.objectNonNull(TypeReference.createExactTrusted(singleType)), fixedGuard));
                }
            }
        }
    }
    boolean nonNull = ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
    if (castNode == null) {
        LogicNode condition = genUnique(createInstanceOfAllowNull(checkedType, object, null));
        if (condition.isTautology()) {
            castNode = object;
        } else {
            FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
            castNode = append(PiNode.create(object, StampFactory.object(checkedType, nonNull), fixedGuard));
        }
    }
    frameState.push(JavaKind.Object, castNode);
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) 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) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 7 with JavaTypeProfile

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

the class BytecodeParser method appendInvoke.

protected Invoke appendInvoke(InvokeKind initialInvokeKind, ResolvedJavaMethod initialTargetMethod, ValueNode[] args) {
    ResolvedJavaMethod targetMethod = initialTargetMethod;
    InvokeKind invokeKind = initialInvokeKind;
    if (initialInvokeKind.isIndirect()) {
        ResolvedJavaType contextType = this.frameState.getMethod().getDeclaringClass();
        ResolvedJavaMethod specialCallTarget = MethodCallTargetNode.findSpecialCallTarget(initialInvokeKind, args[0], initialTargetMethod, contextType);
        if (specialCallTarget != null) {
            invokeKind = InvokeKind.Special;
            targetMethod = specialCallTarget;
        }
    }
    JavaKind resultType = targetMethod.getSignature().getReturnKind();
    if (!parsingIntrinsic() && DeoptALot.getValue(options)) {
        append(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint));
        frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, graph));
        return null;
    }
    JavaType returnType = targetMethod.getSignature().getReturnType(method.getDeclaringClass());
    if (graphBuilderConfig.eagerResolving() || parsingIntrinsic()) {
        returnType = returnType.resolve(targetMethod.getDeclaringClass());
    }
    if (invokeKind.hasReceiver()) {
        args[0] = emitExplicitExceptions(args[0]);
    }
    if (initialInvokeKind == InvokeKind.Special && !targetMethod.isConstructor()) {
        emitCheckForInvokeSuperSpecial(args);
    }
    InlineInfo inlineInfo = null;
    try {
        currentInvoke = new CurrentInvoke(args, invokeKind, returnType);
        if (tryNodePluginForInvocation(args, targetMethod)) {
            if (TraceParserPlugins.getValue(options)) {
                traceWithContext("used node plugin for %s", targetMethod.format("%h.%n(%p)"));
            }
            return null;
        }
        if (invokeKind.hasReceiver() && args[0].isNullConstant()) {
            append(new DeoptimizeNode(InvalidateRecompile, NullCheckException));
            return null;
        }
        if (!invokeKind.isIndirect() || (UseGuardedIntrinsics.getValue(options) && !GeneratePIC.getValue(options))) {
            if (tryInvocationPlugin(invokeKind, args, targetMethod, resultType, returnType)) {
                if (TraceParserPlugins.getValue(options)) {
                    traceWithContext("used invocation plugin for %s", targetMethod.format("%h.%n(%p)"));
                }
                return null;
            }
        }
        if (invokeKind.isDirect()) {
            inlineInfo = tryInline(args, targetMethod);
            if (inlineInfo == SUCCESSFULLY_INLINED) {
                return null;
            }
        }
    } finally {
        currentInvoke = null;
    }
    int invokeBci = bci();
    JavaTypeProfile profile = getProfileForInvoke(invokeKind);
    ExceptionEdgeAction edgeAction = getActionForInvokeExceptionEdge(inlineInfo);
    boolean partialIntrinsicExit = false;
    if (intrinsicContext != null && intrinsicContext.isCallToOriginal(targetMethod)) {
        partialIntrinsicExit = true;
        ResolvedJavaMethod originalMethod = intrinsicContext.getOriginalMethod();
        BytecodeParser intrinsicCallSiteParser = getNonIntrinsicAncestor();
        if (intrinsicCallSiteParser != null) {
            // When exiting a partial intrinsic, the invoke to the original
            // must use the same context as the call to the intrinsic.
            invokeBci = intrinsicCallSiteParser.bci();
            profile = intrinsicCallSiteParser.getProfileForInvoke(invokeKind);
            edgeAction = intrinsicCallSiteParser.getActionForInvokeExceptionEdge(inlineInfo);
        } else {
            // so the bci must be set to unknown, so that the inliner patches it later.
            assert intrinsicContext.isPostParseInlined();
            invokeBci = BytecodeFrame.UNKNOWN_BCI;
            profile = null;
            edgeAction = graph.method().getAnnotation(Snippet.class) == null ? ExceptionEdgeAction.INCLUDE_AND_HANDLE : ExceptionEdgeAction.OMIT;
        }
        if (originalMethod.isStatic()) {
            invokeKind = InvokeKind.Static;
        } else {
            // The original call to the intrinsic must have been devirtualized
            // otherwise we wouldn't be here.
            invokeKind = InvokeKind.Special;
        }
        Signature sig = originalMethod.getSignature();
        returnType = sig.getReturnType(method.getDeclaringClass());
        resultType = sig.getReturnKind();
        assert intrinsicContext.allowPartialIntrinsicArgumentMismatch() || checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
        targetMethod = originalMethod;
    }
    Invoke invoke = createNonInlinedInvoke(edgeAction, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
    if (partialIntrinsicExit) {
        // This invoke must never be later inlined as it might select the intrinsic graph.
        // Until there is a mechanism to guarantee that any late inlining will not select
        // the intrinsic graph, prevent this invoke from being inlined.
        invoke.setUseForInlining(false);
    }
    return invoke;
}
Also used : InlineInfo(org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo) Snippet(org.graalvm.compiler.api.replacements.Snippet) InvokeKind(org.graalvm.compiler.nodes.CallTargetNode.InvokeKind) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) ResolveClassBeforeStaticInvoke(org.graalvm.compiler.core.common.GraalOptions.ResolveClassBeforeStaticInvoke) Invoke(org.graalvm.compiler.nodes.Invoke) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) Signature(jdk.vm.ci.meta.Signature) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 8 with JavaTypeProfile

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

the class StaticAnalysisResultsBuilder method makeResults.

public StaticAnalysisResults makeResults(AnalysisMethod method) {
    MethodTypeFlow methodFlow = method.getTypeFlow();
    MethodFlowsGraph originalFlows = methodFlow.getOriginalMethodFlows();
    ArrayList<JavaTypeProfile> paramProfiles = new ArrayList<>(originalFlows.getParameters().length);
    for (int i = 0; i < originalFlows.getParameters().length; i++) {
        JavaTypeProfile paramProfile = makeTypeProfile(methodFlow.foldTypeFlow(bb, originalFlows.getParameter(i)));
        if (paramProfile != null) {
            ensureSize(paramProfiles, i);
            paramProfiles.set(i, paramProfile);
        }
    }
    JavaTypeProfile[] parameterTypeProfiles = null;
    if (paramProfiles.size() > 0) {
        parameterTypeProfiles = paramProfiles.toArray(new JavaTypeProfile[paramProfiles.size()]);
    }
    JavaTypeProfile resultTypeProfile = makeTypeProfile(methodFlow.foldTypeFlow(bb, originalFlows.getResult()));
    ArrayList<BytecodeEntry> entries = new ArrayList<>(method.getCodeSize());
    for (InstanceOfTypeFlow originalInstanceOf : originalFlows.getInstaceOfFlows()) {
        if (BytecodeLocation.hasValidBci(originalInstanceOf.getLocation())) {
            int bci = originalInstanceOf.getLocation().getBci();
            /* Fold the instanceof flows. */
            TypeState instanceOfTypeState = methodFlow.foldTypeFlow(bb, originalInstanceOf);
            originalInstanceOf.setState(bb, instanceOfTypeState);
            JavaTypeProfile typeProfile = makeTypeProfile(instanceOfTypeState);
            if (typeProfile != null) {
                ensureSize(entries, bci);
                assert entries.get(bci) == null : "In " + method.format("%h.%n(%p)") + " a profile with bci=" + bci + " already exists: " + entries.get(bci);
                entries.set(bci, createBytecodeEntry(method, bci, typeProfile, null, null));
            }
        }
    }
    for (InvokeTypeFlow originalInvoke : originalFlows.getInvokes()) {
        if (BytecodeLocation.hasValidBci(originalInvoke.getLocation())) {
            int bci = originalInvoke.getLocation().getBci();
            TypeState invokeTypeState = TypeState.forEmpty();
            if (originalInvoke.getTargetMethod().hasReceiver()) {
                invokeTypeState = methodFlow.foldTypeFlow(bb, originalInvoke.getReceiver());
                originalInvoke.setState(bb, invokeTypeState);
            }
            TypeFlow<?> originalReturn = originalInvoke.getActualReturn();
            TypeState returnTypeState = null;
            if (originalReturn != null) {
                returnTypeState = methodFlow.foldTypeFlow(bb, originalReturn);
                originalReturn.setState(bb, returnTypeState);
            }
            JavaTypeProfile typeProfile = makeTypeProfile(invokeTypeState);
            JavaMethodProfile methodProfile = makeMethodProfile(originalInvoke.getCallees());
            JavaTypeProfile invokeResultTypeProfile = originalReturn == null ? null : makeTypeProfile(returnTypeState);
            if (typeProfile != null || methodProfile != null || invokeResultTypeProfile != null) {
                ensureSize(entries, bci);
                assert entries.get(bci) == null : "In " + method.format("%h.%n(%p)") + " a profile with bci=" + bci + " already exists: " + entries.get(bci);
                entries.set(bci, createBytecodeEntry(method, bci, typeProfile, methodProfile, invokeResultTypeProfile));
            }
        }
    }
    if (PointstoOptions.PrintSynchronizedAnalysis.getValue(bb.getOptions())) {
        originalFlows.getMonitorEntries().stream().filter(m -> m.getState().typesCount() > 20).sorted(Comparator.comparingInt(m2 -> m2.getState().typesCount())).forEach(monitorEnter -> {
            TypeState monitorEntryState = monitorEnter.getState();
            String typesString = monitorEntryState.closeToAllInstantiated(bb) ? "close to all instantiated" : StreamSupport.stream(monitorEntryState.types().spliterator(), false).map(AnalysisType::getName).collect(Collectors.joining(", "));
            StringBuilder strb = new StringBuilder();
            strb.append("Location: ");
            String methodName = method.format("%h.%n(%p)");
            int bci = monitorEnter.getLocation().getBci();
            if (bci != BytecodeLocation.UNKNOWN_BCI) {
                StackTraceElement traceElement = method.asStackTraceElement(bci);
                String sourceLocation = traceElement.getFileName() + ":" + traceElement.getLineNumber();
                strb.append("@(").append(methodName).append(":").append(bci).append(")");
                strb.append("=(").append(sourceLocation).append(")");
            } else {
                strb.append("@(").append(methodName).append(")");
            }
            strb.append("\n");
            strb.append("Synchronized types #: ").append(monitorEntryState.typesCount()).append("\n");
            strb.append("Types: ").append(typesString).append("\n");
            System.out.println(strb);
        });
    }
    BytecodeEntry first = null;
    for (int i = entries.size() - 1; i >= 0; i--) {
        BytecodeEntry cur = entries.get(i);
        if (cur != null) {
            cur.next = first;
            first = cur;
        }
    }
    return createStaticAnalysisResults(method, parameterTypeProfiles, resultTypeProfile, first);
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) BytecodeEntry(com.oracle.graal.pointsto.results.StaticAnalysisResults.BytecodeEntry) ArrayList(java.util.ArrayList) TypeState(com.oracle.graal.pointsto.typestate.TypeState) InstanceOfTypeFlow(com.oracle.graal.pointsto.flow.InstanceOfTypeFlow) JavaMethodProfile(jdk.vm.ci.meta.JavaMethodProfile) InvokeTypeFlow(com.oracle.graal.pointsto.flow.InvokeTypeFlow) MethodTypeFlow(com.oracle.graal.pointsto.flow.MethodTypeFlow) MethodFlowsGraph(com.oracle.graal.pointsto.flow.MethodFlowsGraph) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile)

Example 9 with JavaTypeProfile

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

the class StaticAnalysisResultsBuilder method makeTypeProfile.

private JavaTypeProfile makeTypeProfile(TypeState typeState) {
    if (typeState == null || typeState.isUnknown() || PointstoOptions.AnalysisSizeCutoff.getValue(bb.getOptions()) != -1 && typeState.typesCount() > PointstoOptions.AnalysisSizeCutoff.getValue(bb.getOptions())) {
        return null;
    }
    if (typeState.isEmpty()) {
        synchronized (types0) {
            return cachedTypeProfile(types0, 0, typeState);
        }
    } else if (typeState.isNull()) {
        synchronized (types0) {
            return cachedTypeProfile(types0, 1, typeState);
        }
    } else if (typeState.exactType() != null) {
        if (typeState.canBeNull()) {
            synchronized (types1Null) {
                return cachedTypeProfile(types1Null, typeState.exactType().getId(), typeState);
            }
        } else {
            synchronized (types1NonNull) {
                return cachedTypeProfile(types1NonNull, typeState.exactType().getId(), typeState);
            }
        }
    }
    synchronized (types) {
        JavaTypeProfile created = createTypeProfile(typeState);
        types.putIfAbsent(created, created);
        return created;
    }
}
Also used : JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile)

Example 10 with JavaTypeProfile

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

the class ProfilingInfoTest method testTypeProfile.

private void testTypeProfile(String testSnippet, int bci) {
    ResolvedJavaType stringType = getMetaAccess().lookupJavaType(String.class);
    ResolvedJavaType stringBuilderType = getMetaAccess().lookupJavaType(StringBuilder.class);
    ProfilingInfo info = profile(testSnippet, "ABC");
    JavaTypeProfile typeProfile = info.getTypeProfile(bci);
    Assert.assertEquals(0.0, typeProfile.getNotRecordedProbability(), DELTA);
    Assert.assertEquals(1, typeProfile.getTypes().length);
    Assert.assertEquals(stringType, typeProfile.getTypes()[0].getType());
    Assert.assertEquals(1.0, typeProfile.getTypes()[0].getProbability(), DELTA);
    continueProfiling(testSnippet, new StringBuilder());
    typeProfile = info.getTypeProfile(bci);
    Assert.assertEquals(0.0, typeProfile.getNotRecordedProbability(), DELTA);
    Assert.assertEquals(2, typeProfile.getTypes().length);
    Assert.assertEquals(stringType, typeProfile.getTypes()[0].getType());
    Assert.assertEquals(stringBuilderType, typeProfile.getTypes()[1].getType());
    Assert.assertEquals(0.5, typeProfile.getTypes()[0].getProbability(), DELTA);
    Assert.assertEquals(0.5, typeProfile.getTypes()[1].getProbability(), DELTA);
    resetProfile(testSnippet);
    typeProfile = info.getTypeProfile(bci);
    Assert.assertNull(typeProfile);
}
Also used : JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ProfilingInfo(jdk.vm.ci.meta.ProfilingInfo) 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