Search in sources :

Example 1 with BytecodeLocation

use of com.oracle.graal.pointsto.flow.context.BytecodeLocation in project graal by oracle.

the class MethodTypeFlowBuilder method processNewArray.

protected void processNewArray(NewArrayNode node, TypeFlowsOfNodes state) {
    AnalysisType type = ((AnalysisType) node.elementType()).getArrayClass();
    assert type.isInstantiated();
    Object key = uniqueKey(node);
    BytecodeLocation allocationLabel = bb.analysisPolicy().createAllocationSite(bb, key, method);
    TypeFlowBuilder<?> newArrayBuilder = TypeFlowBuilder.create(bb, node, NewInstanceTypeFlow.class, () -> {
        NewInstanceTypeFlow newArray = createNewArrayTypeFlow(node, type, allocationLabel);
        methodFlow.addAllocation(newArray);
        return newArray;
    });
    state.add(node, newArrayBuilder);
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) BytecodeLocation(com.oracle.graal.pointsto.flow.context.BytecodeLocation)

Example 2 with BytecodeLocation

use of com.oracle.graal.pointsto.flow.context.BytecodeLocation in project graal by oracle.

the class BytecodeAnalysisContext method toString.

@Override
public String toString() {
    StringBuilder result = new StringBuilder();
    String separator = " ";
    for (BytecodeLocation bytecode : labels) {
        result.append(separator).append(bytecode);
        separator = "\t";
    }
    return result.toString();
}
Also used : BytecodeLocation(com.oracle.graal.pointsto.flow.context.BytecodeLocation)

Example 3 with BytecodeLocation

use of com.oracle.graal.pointsto.flow.context.BytecodeLocation in project graal by oracle.

the class BytecodeAnalysisContextPolicy method calleeContext.

/**
 * Captures the context of a method invocation.
 * <p>
 * Iterates over the list of {@linkplain BytecodeAnalysisContext context chains} of the receiver
 * object, i.e. the contexts from which it's allocator method was invoked, and extends each of
 * this chains with the current receiver's {@linkplain AnalysisObject analysis object}. The
 * depth of each context chain is bounded to {@link PointstoOptions#MaxCallingContextDepth}.
 * <p>
 *
 * @param bb the bigbang.
 * @param receiverObject invocation's {@linkplain AnalysisObject receiver object}
 * @return the list of {@link BytecodeAnalysisContext context chains} leading to this invocation
 *         extended with the current receiver object
 */
@Override
public BytecodeAnalysisContext calleeContext(BigBang bb, AnalysisObject receiverObject, BytecodeAnalysisContext callerContext, MethodTypeFlow callee) {
    int maxCalleeContextDepth = callee.getLocalCallingContextDepth();
    /*
         * If the calling context depth is 0 return ContextChain.EMPTY_CONTEXT so that the unique
         * clone is linked in.
         */
    if (maxCalleeContextDepth == 0 || !receiverObject.isAllocationContextSensitiveObject()) {
        return emptyContext();
    }
    AllocationContextSensitiveObject receiverHeapObject = (AllocationContextSensitiveObject) receiverObject;
    /*
         * If the context depth is greater than 0 and the receiver object has context information
         * then extend the receiver's context by appending the receiver object allocation site,
         * otherwise create a context containing the receiver object allocation site.
         */
    BytecodeLocation[] labelList;
    if (receiverHeapObject.allocationContext() != null) {
        labelList = extend(((BytecodeAnalysisContext) receiverHeapObject.allocationContext()).labels(), receiverHeapObject.allocationLabel(), maxCalleeContextDepth);
    } else {
        // TODO remove branch if never taken
        JVMCIError.shouldNotReachHere("CoreAnalysisContextPolicy.merge: receiverHeapObject.heapContext() is null");
        labelList = new BytecodeLocation[] { receiverHeapObject.allocationLabel() };
    }
    return lookupContext(labelList);
}
Also used : AllocationContextSensitiveObject(com.oracle.graal.pointsto.flow.context.object.AllocationContextSensitiveObject) BytecodeLocation(com.oracle.graal.pointsto.flow.context.BytecodeLocation)

Example 4 with BytecodeLocation

use of com.oracle.graal.pointsto.flow.context.BytecodeLocation in project graal by oracle.

the class MethodTypeFlowBuilder method processNewInstance.

protected void processNewInstance(NewInstanceNode node, TypeFlowsOfNodes state) {
    AnalysisType type = (AnalysisType) node.instanceClass();
    assert type.isInstantiated();
    Object key = uniqueKey(node);
    BytecodeLocation allocationLabel = bb.analysisPolicy().createAllocationSite(bb, key, method);
    TypeFlowBuilder<?> newInstanceBuilder = TypeFlowBuilder.create(bb, node, NewInstanceTypeFlow.class, () -> {
        NewInstanceTypeFlow newInstance = createNewInstanceTypeFlow(node, type, allocationLabel);
        /* Instance fields of a new object are initialized to null state in AnalysisField. */
        methodFlow.addAllocation(newInstance);
        return newInstance;
    });
    state.add(node, newInstanceBuilder);
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) BytecodeLocation(com.oracle.graal.pointsto.flow.context.BytecodeLocation)

Example 5 with BytecodeLocation

use of com.oracle.graal.pointsto.flow.context.BytecodeLocation 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)

Aggregations

BytecodeLocation (com.oracle.graal.pointsto.flow.context.BytecodeLocation)5 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)3 TypeFlowBuilder (com.oracle.graal.pointsto.flow.builder.TypeFlowBuilder)1 AllocationContextSensitiveObject (com.oracle.graal.pointsto.flow.context.object.AllocationContextSensitiveObject)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 Node (org.graalvm.compiler.graph.Node)1 NodeIntrinsic (org.graalvm.compiler.graph.Node.NodeIntrinsic)1 NodeBitMap (org.graalvm.compiler.graph.NodeBitMap)1 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)1 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)1 BeginNode (org.graalvm.compiler.nodes.BeginNode)1 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)1 EndNode (org.graalvm.compiler.nodes.EndNode)1 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)1 FixedNode (org.graalvm.compiler.nodes.FixedNode)1 IfNode (org.graalvm.compiler.nodes.IfNode)1 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)1