Search in sources :

Example 1 with InvokeTypeFlow

use of com.oracle.graal.pointsto.flow.InvokeTypeFlow 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 2 with InvokeTypeFlow

use of com.oracle.graal.pointsto.flow.InvokeTypeFlow in project graal by oracle.

the class PointsToStats method asString.

private static String asString(TypeFlow<?> flow) {
    if (flow instanceof AllInstantiatedTypeFlow) {
        return "AllInstantiated(" + formatType(flow.getDeclaredType(), true) + ")";
    } else if (flow instanceof AllSynchronizedTypeFlow) {
        return "AllSynchronized";
    } else if (flow instanceof UnknownTypeFlow) {
        return "Unknown";
    } else if (flow instanceof FieldSinkTypeFlow) {
        FieldSinkTypeFlow sink = (FieldSinkTypeFlow) flow;
        return "FieldSink(" + formatField(sink.getSource()) + ")";
    } else if (flow instanceof FieldTypeFlow) {
        FieldTypeFlow fieldFlow = (FieldTypeFlow) flow;
        AnalysisField field = fieldFlow.getSource();
        return (field.isStatic() ? "StaticField" : "InstanceField") + "(" + formatField(field) + ")";
    } else if (flow instanceof StoreInstanceFieldTypeFlow) {
        StoreInstanceFieldTypeFlow store = (StoreInstanceFieldTypeFlow) flow;
        return "InstanceStore(" + formatField(store.field()) + ")@" + formatSource(flow);
    } else if (flow instanceof StoreStaticFieldTypeFlow) {
        StoreStaticFieldTypeFlow store = (StoreStaticFieldTypeFlow) flow;
        return "StaticStore(" + formatField(store.field()) + ")@" + formatSource(flow);
    } else if (flow instanceof LoadInstanceFieldTypeFlow) {
        LoadInstanceFieldTypeFlow load = (LoadInstanceFieldTypeFlow) flow;
        return "InstanceLoad(" + formatField(load.field()) + ")@" + formatSource(flow);
    } else if (flow instanceof LoadStaticFieldTypeFlow) {
        LoadStaticFieldTypeFlow load = (LoadStaticFieldTypeFlow) flow;
        return "StaticLoad(" + formatField(load.field()) + ")@" + formatSource(flow);
    } else if (flow instanceof StoreIndexedTypeFlow) {
        return "IndexedStore @ " + formatSource(flow);
    } else if (flow instanceof UnsafeStoreTypeFlow) {
        return "UnsafeStore @ " + formatSource(flow);
    } else if (flow instanceof UnsafePartitionStoreTypeFlow) {
        return "UnsafePartitionStore @ " + formatSource(flow);
    } else if (flow instanceof UnsafeWriteSinkTypeFlow) {
        UnsafeWriteSinkTypeFlow sink = (UnsafeWriteSinkTypeFlow) flow;
        return "UnsafeWriteSink(" + formatField(sink.getSource()) + ")";
    } else if (flow instanceof JavaWriteTypeFlow) {
        return "JavaWrite @ " + formatSource(flow);
    } else if (flow instanceof AtomicWriteTypeFlow) {
        return "AtomicWrite @ " + formatSource(flow);
    } else if (flow instanceof CompareAndSwapTypeFlow) {
        return "CompareAndSwap @ " + formatSource(flow);
    } else if (flow instanceof LoadIndexedTypeFlow) {
        return "IndexedLoad @ " + formatSource(flow);
    } else if (flow instanceof UnsafeLoadTypeFlow) {
        return "UnsafeLoad @ " + formatSource(flow);
    } else if (flow instanceof UnsafePartitionLoadTypeFlow) {
        return "UnsafePartitionLoad @ " + formatSource(flow);
    } else if (flow instanceof JavaReadTypeFlow) {
        return "JavaRead @ " + formatSource(flow);
    } else if (flow instanceof AtomicReadTypeFlow) {
        return "AtomicRead @ " + formatSource(flow);
    } else if (flow instanceof ArrayElementsTypeFlow) {
        ArrayElementsTypeFlow arrayFlow = (ArrayElementsTypeFlow) flow;
        return "ArrayElements(" + (arrayFlow.object() != null ? arrayFlow.object().type().toJavaName(false) : "?") + ")";
    } else if (flow instanceof NullCheckTypeFlow) {
        NullCheckTypeFlow nullCheck = (NullCheckTypeFlow) flow;
        return "NullCheck(" + (nullCheck.isFilterNull() ? "not-null" : "only-null") + ")@" + formatSource(flow);
    } else if (flow instanceof FilterTypeFlow) {
        FilterTypeFlow filter = (FilterTypeFlow) flow;
        String properties = filter.isExact() ? "exact" : "not-exact";
        properties += ", " + (filter.isAssignable() ? "assignable" : "not-assignable");
        properties += ", " + (filter.includeNull() ? "include-null" : "not-include-null");
        return "Filter(" + properties + ", " + formatType(filter.getType(), true) + ")@" + formatSource(flow);
    } else if (flow instanceof FieldFilterTypeFlow) {
        FieldFilterTypeFlow filter = (FieldFilterTypeFlow) flow;
        return "FieldFilter(" + formatField(filter.getSource()) + ")";
    } else if (flow instanceof FrozenFieldFilterTypeFlow) {
        FrozenFieldFilterTypeFlow filter = (FrozenFieldFilterTypeFlow) flow;
        return "FrozenFieldFilter(" + formatField(filter.getSource()) + ")";
    } else if (flow instanceof InstanceOfTypeFlow) {
        InstanceOfTypeFlow instanceOf = (InstanceOfTypeFlow) flow;
        return "InstanceOf(" + formatType(instanceOf.getDeclaredType(), true) + ")@" + formatSource(flow);
    } else if (flow instanceof NewInstanceTypeFlow) {
        return "NewInstance(" + flow.getDeclaredType().toJavaName(false) + ")@" + formatSource(flow);
    } else if (flow instanceof DynamicNewInstanceTypeFlow) {
        return "DynamicNewInstance @ " + formatSource(flow);
    } else if (flow instanceof InvokeTypeFlow) {
        InvokeTypeFlow invoke = (InvokeTypeFlow) flow;
        return "Invoke(" + formatMethod(invoke.getTargetMethod()) + ")@" + formatSource(flow);
    } else if (flow instanceof InitialParamTypeFlow) {
        InitialParamTypeFlow param = (InitialParamTypeFlow) flow;
        return "InitialParam(" + param.position() + ")@" + formatMethod(param.method());
    } else if (flow instanceof FormalParamTypeFlow) {
        FormalParamTypeFlow param = (FormalParamTypeFlow) flow;
        return "Parameter(" + param.position() + ")@" + formatMethod(param.method());
    } else if (flow instanceof FormalReturnTypeFlow) {
        return "Return @ " + formatSource(flow);
    } else if (flow instanceof ActualReturnTypeFlow) {
        ActualReturnTypeFlow ret = (ActualReturnTypeFlow) flow;
        InvokeTypeFlow invoke = ret.invokeFlow();
        return "ActualReturn(" + formatMethod(invoke.getTargetMethod()) + ")@ " + formatSource(flow);
    } else if (flow instanceof MergeTypeFlow) {
        return "Merge @ " + formatSource(flow);
    } else if (flow instanceof SourceTypeFlow) {
        return "Source @ " + formatSource(flow);
    } else if (flow instanceof CloneTypeFlow) {
        return "Clone @ " + formatSource(flow);
    } else if (flow instanceof MonitorEnterTypeFlow) {
        MonitorEnterTypeFlow monitor = (MonitorEnterTypeFlow) flow;
        return "MonitorEnter @ " + formatMethod(monitor.getMethod());
    } else {
        return flow.getClass().getSimpleName() + "@" + formatSource(flow);
    }
}
Also used : MonitorEnterTypeFlow(com.oracle.graal.pointsto.flow.MonitorEnterTypeFlow) JavaReadTypeFlow(com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.JavaReadTypeFlow) LoadInstanceFieldTypeFlow(com.oracle.graal.pointsto.flow.LoadFieldTypeFlow.LoadInstanceFieldTypeFlow) FieldFilterTypeFlow(com.oracle.graal.pointsto.flow.FieldFilterTypeFlow) FrozenFieldFilterTypeFlow(com.oracle.graal.pointsto.flow.FrozenFieldFilterTypeFlow) FormalParamTypeFlow(com.oracle.graal.pointsto.flow.FormalParamTypeFlow) SourceTypeFlow(com.oracle.graal.pointsto.flow.SourceTypeFlow) ActualReturnTypeFlow(com.oracle.graal.pointsto.flow.ActualReturnTypeFlow) NullCheckTypeFlow(com.oracle.graal.pointsto.flow.NullCheckTypeFlow) DynamicNewInstanceTypeFlow(com.oracle.graal.pointsto.flow.DynamicNewInstanceTypeFlow) UnsafeWriteSinkTypeFlow(com.oracle.graal.pointsto.flow.UnsafeWriteSinkTypeFlow) InvokeTypeFlow(com.oracle.graal.pointsto.flow.InvokeTypeFlow) LoadIndexedTypeFlow(com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.LoadIndexedTypeFlow) ArrayElementsTypeFlow(com.oracle.graal.pointsto.flow.ArrayElementsTypeFlow) DynamicNewInstanceTypeFlow(com.oracle.graal.pointsto.flow.DynamicNewInstanceTypeFlow) NewInstanceTypeFlow(com.oracle.graal.pointsto.flow.NewInstanceTypeFlow) UnsafeLoadTypeFlow(com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.UnsafeLoadTypeFlow) AllInstantiatedTypeFlow(com.oracle.graal.pointsto.flow.AllInstantiatedTypeFlow) UnsafePartitionLoadTypeFlow(com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.UnsafePartitionLoadTypeFlow) CloneTypeFlow(com.oracle.graal.pointsto.flow.CloneTypeFlow) FieldSinkTypeFlow(com.oracle.graal.pointsto.flow.FieldSinkTypeFlow) JavaWriteTypeFlow(com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow.JavaWriteTypeFlow) AtomicWriteTypeFlow(com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow.AtomicWriteTypeFlow) StoreStaticFieldTypeFlow(com.oracle.graal.pointsto.flow.StoreFieldTypeFlow.StoreStaticFieldTypeFlow) StoreInstanceFieldTypeFlow(com.oracle.graal.pointsto.flow.StoreFieldTypeFlow.StoreInstanceFieldTypeFlow) LoadStaticFieldTypeFlow(com.oracle.graal.pointsto.flow.LoadFieldTypeFlow.LoadStaticFieldTypeFlow) FieldTypeFlow(com.oracle.graal.pointsto.flow.FieldTypeFlow) LoadInstanceFieldTypeFlow(com.oracle.graal.pointsto.flow.LoadFieldTypeFlow.LoadInstanceFieldTypeFlow) FormalReturnTypeFlow(com.oracle.graal.pointsto.flow.FormalReturnTypeFlow) MergeTypeFlow(com.oracle.graal.pointsto.flow.MergeTypeFlow) UnsafePartitionStoreTypeFlow(com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow.UnsafePartitionStoreTypeFlow) UnknownTypeFlow(com.oracle.graal.pointsto.flow.UnknownTypeFlow) AnalysisField(com.oracle.graal.pointsto.meta.AnalysisField) InstanceOfTypeFlow(com.oracle.graal.pointsto.flow.InstanceOfTypeFlow) FilterTypeFlow(com.oracle.graal.pointsto.flow.FilterTypeFlow) FieldFilterTypeFlow(com.oracle.graal.pointsto.flow.FieldFilterTypeFlow) FrozenFieldFilterTypeFlow(com.oracle.graal.pointsto.flow.FrozenFieldFilterTypeFlow) AtomicReadTypeFlow(com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.AtomicReadTypeFlow) AllSynchronizedTypeFlow(com.oracle.graal.pointsto.flow.AllSynchronizedTypeFlow) CompareAndSwapTypeFlow(com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow.CompareAndSwapTypeFlow) StoreStaticFieldTypeFlow(com.oracle.graal.pointsto.flow.StoreFieldTypeFlow.StoreStaticFieldTypeFlow) StoreIndexedTypeFlow(com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow.StoreIndexedTypeFlow) InitialParamTypeFlow(com.oracle.graal.pointsto.flow.InitialParamTypeFlow) LoadStaticFieldTypeFlow(com.oracle.graal.pointsto.flow.LoadFieldTypeFlow.LoadStaticFieldTypeFlow) FrozenFieldFilterTypeFlow(com.oracle.graal.pointsto.flow.FrozenFieldFilterTypeFlow) StoreInstanceFieldTypeFlow(com.oracle.graal.pointsto.flow.StoreFieldTypeFlow.StoreInstanceFieldTypeFlow) UnsafeStoreTypeFlow(com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow.UnsafeStoreTypeFlow)

Example 3 with InvokeTypeFlow

use of com.oracle.graal.pointsto.flow.InvokeTypeFlow in project graal by oracle.

the class RuntimeStrengthenStampsPhase method processMethod.

@SuppressWarnings("try")
private void processMethod(CallTreeNode node, Deque<CallTreeNode> worklist, BigBang bb) {
    AnalysisMethod method = node.implementationMethod;
    assert method.isImplementationInvoked();
    if (node.graph == null) {
        if (method.getAnnotation(Fold.class) != null || method.getAnnotation(NodeIntrinsic.class) != null) {
            VMError.shouldNotReachHere("Parsing method annotated with @Fold or @NodeIntrinsic: " + method.format("%H.%n(%p)"));
        }
        boolean parse = false;
        DebugContext debug = bb.getDebug();
        StructuredGraph graph = method.buildGraph(debug, method, hostedProviders, Purpose.PREPARE_RUNTIME_COMPILATION);
        if (graph == null) {
            if (!method.hasBytecodes()) {
                return;
            }
            parse = true;
            graph = new StructuredGraph.Builder(debug.getOptions(), debug, AllowAssumptions.YES).method(method).build();
        }
        try (DebugContext.Scope scope = debug.scope("RuntimeCompile", graph)) {
            if (parse) {
                RuntimeGraphBuilderPhase builderPhase = new RuntimeGraphBuilderPhase(hostedProviders.getMetaAccess(), hostedProviders.getStampProvider(), hostedProviders.getConstantReflection(), hostedProviders.getConstantFieldProvider(), graphBuilderConfig, optimisticOpts, null, hostedProviders.getWordTypes(), deoptimizeOnExceptionPredicate, node);
                builderPhase.apply(graph);
            }
            if (graph.getNodes(StackValueNode.TYPE).isNotEmpty()) {
                /*
                     * Stack allocated memory is not seen by the deoptimization code, i.e., it is
                     * not copied in case of deoptimization. Also, pointers to it can be used for
                     * arbitrary address arithmetic, so we would not know how to update derived
                     * pointers into stack memory during deoptimization. Therefore, we cannot allow
                     * methods that allocate stack memory for runtime compilation. To remove this
                     * limitation, we would need to change how we handle stack allocated memory in
                     * Graal.
                     */
                return;
            }
            PhaseContext phaseContext = new PhaseContext(hostedProviders);
            new CanonicalizerPhase().apply(graph, phaseContext);
            new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext);
            graphEncoder.prepare(graph);
            node.graph = graph;
        } catch (Throwable ex) {
            debug.handle(ex);
        }
    }
    assert node.graph != null;
    List<MethodCallTargetNode> callTargets = node.graph.getNodes(MethodCallTargetNode.TYPE).snapshot();
    callTargets.sort((t1, t2) -> Integer.compare(t1.invoke().bci(), t2.invoke().bci()));
    for (MethodCallTargetNode targetNode : callTargets) {
        AnalysisMethod targetMethod = (AnalysisMethod) targetNode.targetMethod();
        AnalysisMethod callerMethod = (AnalysisMethod) targetNode.invoke().stateAfter().getMethod();
        InvokeTypeFlow invokeFlow = callerMethod.getTypeFlow().getOriginalMethodFlows().getInvoke(targetNode.invoke().bci());
        if (invokeFlow == null) {
            continue;
        }
        Collection<AnalysisMethod> allImplementationMethods = invokeFlow.getCallees();
        /*
             * Eventually we want to remove all invokes that are unreachable, i.e., have no
             * implementation. But the analysis is iterative, and we don't know here if we have
             * already reached the fixed point. So we only collect unreachable invokes here, and
             * remove them after the analysis has finished.
             */
        if (allImplementationMethods.size() == 0) {
            node.unreachableInvokes.add(targetNode.invoke());
        } else {
            node.unreachableInvokes.remove(targetNode.invoke());
        }
        List<AnalysisMethod> implementationMethods = new ArrayList<>();
        for (AnalysisMethod implementationMethod : allImplementationMethods) {
            /* Filter out all the implementation methods that have already been processed. */
            if (!methods.containsKey(implementationMethod)) {
                implementationMethods.add(implementationMethod);
            }
        }
        if (implementationMethods.size() > 0) {
            /* Sort to make printing order and method discovery order deterministic. */
            implementationMethods.sort((m1, m2) -> m1.format("%H.%n(%p)").compareTo(m2.format("%H.%n(%p)")));
            String sourceReference = buildSourceReference(targetNode.invoke().stateAfter());
            for (AnalysisMethod implementationMethod : implementationMethods) {
                CallTreeNode calleeNode = new CallTreeNode(implementationMethod, targetMethod, node, node.level + 1, sourceReference);
                if (includeCalleePredicate.includeCallee(calleeNode, implementationMethods)) {
                    assert !methods.containsKey(implementationMethod);
                    methods.put(implementationMethod, calleeNode);
                    worklist.add(calleeNode);
                    node.children.add(calleeNode);
                    objectReplacer.createMethod(implementationMethod);
                }
                /*
                     * We must compile all methods which may be called. It may be the case that a
                     * call target does not reach the compile queue by default, e.g. if it is
                     * inlined at image generation but not at runtime compilation.
                     */
                CompilationInfoSupport.singleton().registerForcedCompilation(implementationMethod);
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) DebugContext(org.graalvm.compiler.debug.DebugContext) InvokeTypeFlow(com.oracle.graal.pointsto.flow.InvokeTypeFlow) ConvertDeoptimizeToGuardPhase(org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase) PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) AnalysisMethod(com.oracle.graal.pointsto.meta.AnalysisMethod) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase)

Example 4 with InvokeTypeFlow

use of com.oracle.graal.pointsto.flow.InvokeTypeFlow in project graal by oracle.

the class ShortestInvokeChainPrinter method print.

public static void print(BigBang bb, AnalysisMethod target, PrintStream out) {
    Deque<AnalysisMethod> workList = new LinkedList<>();
    Map<AnalysisMethod, Element> visited = new HashMap<>();
    for (AnalysisMethod m : bb.getUniverse().getMethods()) {
        if (m.isEntryPoint()) {
            workList.addLast(m);
            visited.put(m, new Element(m, null, null));
        }
    }
    while (workList.size() > 0) {
        AnalysisMethod method = workList.removeFirst();
        Element methodElement = visited.get(method);
        assert methodElement != null;
        for (InvokeTypeFlow invoke : method.getTypeFlow().getInvokes()) {
            for (AnalysisMethod callee : invoke.getCallees()) {
                if (visited.containsKey(callee)) {
                    // We already had a shorter path to this method.
                    continue;
                }
                Element calleeElement = new Element(callee, methodElement, invoke);
                visited.put(callee, calleeElement);
                if (callee.equals(target)) {
                    // We found a path from an entry point to our target method.
                    printPath(calleeElement, out);
                    return;
                } else {
                    workList.addLast(callee);
                }
            }
        }
    }
    printNoPath(out);
}
Also used : AnalysisMethod(com.oracle.graal.pointsto.meta.AnalysisMethod) HashMap(java.util.HashMap) InvokeTypeFlow(com.oracle.graal.pointsto.flow.InvokeTypeFlow) LinkedList(java.util.LinkedList)

Aggregations

InvokeTypeFlow (com.oracle.graal.pointsto.flow.InvokeTypeFlow)4 InstanceOfTypeFlow (com.oracle.graal.pointsto.flow.InstanceOfTypeFlow)2 AnalysisMethod (com.oracle.graal.pointsto.meta.AnalysisMethod)2 ArrayList (java.util.ArrayList)2 ActualReturnTypeFlow (com.oracle.graal.pointsto.flow.ActualReturnTypeFlow)1 AllInstantiatedTypeFlow (com.oracle.graal.pointsto.flow.AllInstantiatedTypeFlow)1 AllSynchronizedTypeFlow (com.oracle.graal.pointsto.flow.AllSynchronizedTypeFlow)1 ArrayElementsTypeFlow (com.oracle.graal.pointsto.flow.ArrayElementsTypeFlow)1 CloneTypeFlow (com.oracle.graal.pointsto.flow.CloneTypeFlow)1 DynamicNewInstanceTypeFlow (com.oracle.graal.pointsto.flow.DynamicNewInstanceTypeFlow)1 FieldFilterTypeFlow (com.oracle.graal.pointsto.flow.FieldFilterTypeFlow)1 FieldSinkTypeFlow (com.oracle.graal.pointsto.flow.FieldSinkTypeFlow)1 FieldTypeFlow (com.oracle.graal.pointsto.flow.FieldTypeFlow)1 FilterTypeFlow (com.oracle.graal.pointsto.flow.FilterTypeFlow)1 FormalParamTypeFlow (com.oracle.graal.pointsto.flow.FormalParamTypeFlow)1 FormalReturnTypeFlow (com.oracle.graal.pointsto.flow.FormalReturnTypeFlow)1 FrozenFieldFilterTypeFlow (com.oracle.graal.pointsto.flow.FrozenFieldFilterTypeFlow)1 InitialParamTypeFlow (com.oracle.graal.pointsto.flow.InitialParamTypeFlow)1 LoadInstanceFieldTypeFlow (com.oracle.graal.pointsto.flow.LoadFieldTypeFlow.LoadInstanceFieldTypeFlow)1 LoadStaticFieldTypeFlow (com.oracle.graal.pointsto.flow.LoadFieldTypeFlow.LoadStaticFieldTypeFlow)1