Search in sources :

Example 16 with TypeState

use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.

the class ArrayCopyTypeFlow method onObservedUpdate.

@Override
public void onObservedUpdate(BigBang bb) {
    assert this.isClone();
    /*
         * Both the source and the destination register this flow as an observer and notify it when
         * either of them is updated. When either the source or the destination elements change the
         * element flows from source are passed to destination.
         */
    TypeState srcArrayState = srcArrayFlow.getState();
    TypeState dstArrayState = dstArrayFlow.getState();
    /*
         * The source and destination array can have reference types which, although must be
         * compatible, can be different.
         */
    for (AnalysisObject srcArrayObject : srcArrayState.objects()) {
        if (!srcArrayObject.type().isArray()) {
            /*
                 * Ignore non-array type. Sometimes the analysis cannot filter out non-array types
                 * flowing into array copy, however this will fail at runtime.
                 */
            continue;
        }
        assert srcArrayObject.type().isArray();
        if (srcArrayObject.isPrimitiveArray() || srcArrayObject.isEmptyObjectArrayConstant(bb)) {
            /* Nothing to read from a primitive array or an empty array constant. */
            continue;
        }
        ArrayElementsTypeFlow srcArrayElementsFlow = srcArrayObject.getArrayElementsFlow(bb, false);
        for (AnalysisObject dstArrayObject : dstArrayState.objects()) {
            if (!dstArrayObject.type().isArray()) {
                /* Ignore non-array type. */
                continue;
            }
            assert dstArrayObject.type().isArray();
            if (dstArrayObject.isPrimitiveArray() || dstArrayObject.isEmptyObjectArrayConstant(bb)) {
                /* Cannot write to a primitive array or an empty array constant. */
                continue;
            }
            /*
                 * As far as the ArrayCopyTypeFlow is concerned the source and destination types can
                 * be compatible or not, where compatibility is defined as: the component of the
                 * source array can be converted to the component type of the destination array by
                 * assignment conversion. System.arraycopy() semantics doesn't check the
                 * compatibility of the source and destination arrays, it instead relies on runtime
                 * checks of the compatibility of the copied objects and the destination array. For
                 * example System.arraycopy() can copy from an Object[] to SomeOtherObject[]. In
                 * this case a check dstArrayObject.type().isAssignableFrom(srcArrayObject.type()
                 * would fail but it is actually a valid use. That's why ArrayElementsTypeFlow will
                 * test each individual copied object for compatibility with the defined type of the
                 * destination array and filter out those not assignable. From System.arraycopy()
                 * javadoc: "...if any actual component of the source array from position srcPos
                 * through srcPos+length-1 cannot be converted to the component type of the
                 * destination array by assignment conversion, an ArrayStoreException is thrown."
                 */
            ArrayElementsTypeFlow dstArrayElementsFlow = dstArrayObject.getArrayElementsFlow(bb, true);
            srcArrayElementsFlow.addUse(bb, dstArrayElementsFlow);
        }
    }
}
Also used : AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject) TypeState(com.oracle.graal.pointsto.typestate.TypeState)

Example 17 with TypeState

use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.

the class ProxyTypeFlow method update.

@Override
public void update(BigBang bb) {
    // propagate input state to uses
    TypeState curState = input.getState();
    for (TypeFlow<?> use : getUses()) {
        use.addState(bb, curState);
    }
    notifyObservers(bb);
}
Also used : TypeState(com.oracle.graal.pointsto.typestate.TypeState)

Example 18 with TypeState

use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.

the class TypeFlow method addState.

public boolean addState(BigBang bb, TypeState add, boolean postFlow) {
    PointsToStats.registerTypeFlowUpdate(bb, this, add);
    TypeState before;
    TypeState after;
    TypeState filteredAdd;
    do {
        before = state;
        filteredAdd = filter(bb, add);
        after = TypeState.forUnion(bb, before, filteredAdd);
        if (after.equals(before)) {
            return false;
        }
    } while (!STATE_UPDATER.compareAndSet(this, before, after));
    PointsToStats.registerTypeFlowSuccessfulUpdate(bb, this, add);
    /*
         * Checkcast and instanceof type flows no longer reflect a type state that contains only the
         * types assignable to the declared type; they keep track of all the types discovered during
         * analysis and are always followed by a filter type flow that implements the filter
         * operation based on the declared type.
         */
    assert !PointstoOptions.ExtendedAsserts.getValue(bb.getOptions()) || this instanceof InstanceOfTypeFlow || after.verifyDeclaredType(declaredType) : "declaredType: " + declaredType.toJavaName(true) + " after: " + after + " before: " + before + " this: " + this;
    if (postFlow) {
        bb.postFlow(this);
    }
    return true;
}
Also used : TypeState(com.oracle.graal.pointsto.typestate.TypeState)

Example 19 with TypeState

use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.

the class FilterTypeFlow method filter.

@Override
public TypeState filter(BigBang bb, TypeState update) {
    if (update.isUnknown()) {
        // Filtering UnknownTypeState would otherwise return EmptyTypeState.
        AnalysisMethod method = (AnalysisMethod) source.graph().method();
        bb.reportIllegalUnknownUse(method, source, "Illegal: Filter of UnknownTypeState objects.");
        return TypeState.forEmpty();
    }
    TypeState result;
    if (isExact) {
        /*
             * If the filter is exact we only check the update state against the exact type, and not
             * its entire hierarchy.
             */
        if (isAssignable) {
            result = TypeState.forIntersection(bb, update, TypeState.forExactType(bb, type, includeNull));
        } else {
            result = TypeState.forSubtraction(bb, update, TypeState.forExactType(bb, type, !includeNull));
        }
    } else {
        /*
             * If the filter is not exact we check the update state against the entire hierarchy,
             * not only the exact type (AnalysisType.getTypeFlow() returns the type plus all its
             * instantiated sub-types).
             */
        if (isAssignable) {
            result = TypeState.forIntersection(bb, update, type.getTypeFlow(bb, includeNull).getState());
        } else {
            result = TypeState.forSubtraction(bb, update, type.getTypeFlow(bb, !includeNull).getState());
        }
    }
    return result;
}
Also used : AnalysisMethod(com.oracle.graal.pointsto.meta.AnalysisMethod) TypeState(com.oracle.graal.pointsto.typestate.TypeState)

Example 20 with TypeState

use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.

the class NativeImageGenerator method checkUniverse.

private void checkUniverse() {
    /*
         * Check that the type states for method parameters and fields are compatible with the
         * declared type. This is required for interface types because interfaces are not trusted
         * according to the Java language specification, but we trust all interface types (see
         * HostedType.isTrustedInterfaceType)
         *
         * TODO Enable checks for non-interface types too.
         */
    for (AnalysisMethod method : aUniverse.getMethods()) {
        for (int i = 0; i < method.getTypeFlow().getOriginalMethodFlows().getParameters().length; i++) {
            TypeState state = method.getTypeFlow().getParameterTypeState(bigbang, i);
            if (state != null) {
                AnalysisType declaredType = method.getTypeFlow().getOriginalMethodFlows().getParameter(i).getDeclaredType();
                if (declaredType.isInterface()) {
                    state = TypeState.forSubtraction(bigbang, state, declaredType.getTypeFlow(bigbang, true).getState());
                    if (!state.isEmpty()) {
                        bigbang.getUnsupportedFeatures().addMessage(method.format("%H.%n(%p)"), method, "Method parameter " + i + " has declaredType " + declaredType.toJavaName(true) + " and incompatible types in state: " + state);
                    }
                }
            }
        }
    }
    for (AnalysisField field : aUniverse.getFields()) {
        TypeState state = field.getTypeState();
        if (state != null) {
            AnalysisType declaredType = field.getType();
            if (declaredType.isInterface()) {
                state = TypeState.forSubtraction(bigbang, state, declaredType.getTypeFlow(bigbang, true).getState());
                if (!state.isEmpty()) {
                    bigbang.getUnsupportedFeatures().addMessage(field.format("%H.%n"), null, "Field has declaredType " + declaredType.toJavaName(true) + " and incompatible types in state: " + state);
                }
            }
        }
    }
    if (SubstrateOptions.VerifyNamingConventions.getValue()) {
        for (AnalysisMethod method : aUniverse.getMethods()) {
            if ((method.isInvoked() || method.isImplementationInvoked()) && method.getAnnotation(Fold.class) == null) {
                checkName(method.format("%H.%n(%p)"), method);
            }
        }
        for (AnalysisField field : aUniverse.getFields()) {
            if (field.isAccessed()) {
                checkName(field.format("%H.%n"), null);
            }
        }
        for (AnalysisType type : aUniverse.getTypes()) {
            if ((type.isInstantiated() || type.isInTypeCheck())) {
                checkName(type.toJavaName(true), null);
            }
        }
    }
    /*
         * Entry points use a different calling convention (the native C ABI calling convention), so
         * they must not be called from other Java methods.
         */
    for (AnalysisMethod method : aUniverse.getMethods()) {
        if (method.isEntryPoint()) {
            List<AnalysisMethod> invocations = method.getJavaInvocations();
            if (invocations.size() > 0) {
                String name = method.format("%H.%n(%p)");
                StringBuilder msg = new StringBuilder("Native entry point is also called from within Java. Invocations: ");
                String sep = "";
                for (AnalysisMethod invocation : invocations) {
                    msg.append(sep).append(invocation.format("%H.%n(%p)"));
                    sep = ", ";
                }
                bigbang.getUnsupportedFeatures().addMessage(name, method, msg.toString());
            }
        }
    }
// the unsupported features are reported after checkUniverse is invoked
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) AnalysisMethod(com.oracle.graal.pointsto.meta.AnalysisMethod) TypeState(com.oracle.graal.pointsto.typestate.TypeState) AnalysisField(com.oracle.graal.pointsto.meta.AnalysisField) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint)

Aggregations

TypeState (com.oracle.graal.pointsto.typestate.TypeState)22 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)8 AnalysisObject (com.oracle.graal.pointsto.flow.context.object.AnalysisObject)6 AnalysisMethod (com.oracle.graal.pointsto.meta.AnalysisMethod)4 AnalysisContext (com.oracle.graal.pointsto.flow.context.AnalysisContext)3 AnalysisField (com.oracle.graal.pointsto.meta.AnalysisField)3 ArrayList (java.util.ArrayList)3 BigBang (com.oracle.graal.pointsto.BigBang)2 PointstoOptions (com.oracle.graal.pointsto.api.PointstoOptions)2 BytecodeLocation (com.oracle.graal.pointsto.flow.context.BytecodeLocation)2 BitSet (java.util.BitSet)2 ValueNode (org.graalvm.compiler.nodes.ValueNode)2 CEntryPoint (org.graalvm.nativeimage.c.function.CEntryPoint)2 AnalysisPolicy (com.oracle.graal.pointsto.AnalysisPolicy)1 UnsupportedFeatureException (com.oracle.graal.pointsto.constraints.UnsupportedFeatureException)1 AllInstantiatedTypeFlow (com.oracle.graal.pointsto.flow.AllInstantiatedTypeFlow)1 ArrayElementsTypeFlow (com.oracle.graal.pointsto.flow.ArrayElementsTypeFlow)1 FieldTypeFlow (com.oracle.graal.pointsto.flow.FieldTypeFlow)1 InstanceOfTypeFlow (com.oracle.graal.pointsto.flow.InstanceOfTypeFlow)1 InvokeTypeFlow (com.oracle.graal.pointsto.flow.InvokeTypeFlow)1