Search in sources :

Example 1 with Range

use of com.oracle.graal.pointsto.typestate.MultiTypeState.Range in project graal by oracle.

the class UnknownTypeState method doUnion.

private static TypeState doUnion(BigBang bb, MultiTypeState s1, SingleTypeState s2) {
    boolean resultCanBeNull = s1.canBeNull() || s2.canBeNull();
    if (s2.objects.length == 1 && s1.containsObject(s2.objects[0])) {
        /*
             * Speculate that s2 has a single object and s1 already contains that object. This
             * happens often during object scanning where we repeatedly add the scanned constants to
             * field or array elements flows. The binary search executed by containsObject should be
             * faster than the linear search bellow.
             */
        return s1.forCanBeNull(bb, resultCanBeNull);
    }
    if (s1.containsType(s2.exactType())) {
        /* Objects of the same type as s2 are contained in s1. */
        /* Get the range of objects in s1 corresponding to the type of s2. */
        Range typeRange = s1.findTypeRange(s2.exactType());
        /* Get the slice of objects in s1 corresponding to the type of s2. */
        AnalysisObject[] s1ObjectsSlice = s1.objectsArray(typeRange);
        /* Create the resulting objects array. */
        AnalysisObject[] unionObjects = TypeStateUtils.union(bb, s1ObjectsSlice, s2.objects);
        /* Check if s1 contains s2's objects for this type. */
        if (unionObjects == s1ObjectsSlice) {
            return s1.forCanBeNull(bb, resultCanBeNull);
        }
        /*
             * Due to the test above and to the fact that TypeStateUtils.union checks if one array
             * contains the other the union set cannot be equal to s1's objects slice.
             */
        assert !PointstoOptions.ExtendedAsserts.getValue(bb.getOptions()) || !Arrays.equals(unionObjects, s1ObjectsSlice);
        /*
             * Replace the s1 objects slice of the same type as s2 with the union objects and create
             * a new state.
             */
        int resultSize = s1.objects.length + unionObjects.length - s1ObjectsSlice.length;
        AnalysisObject[] resultObjects = new AnalysisObject[resultSize];
        System.arraycopy(s1.objects, 0, resultObjects, 0, typeRange.left);
        System.arraycopy(unionObjects, 0, resultObjects, typeRange.left, unionObjects.length);
        System.arraycopy(s1.objects, typeRange.right, resultObjects, typeRange.left + unionObjects.length, s1.objects.length - typeRange.right);
        /* The types bit set of the result and s1 are the same. */
        int properties = bb.analysisPolicy().makePopertiesForUnion(s1, s2);
        MultiTypeState result = new MultiTypeState(bb, resultCanBeNull, properties, s1.typesBitSet, resultObjects);
        assert !result.equals(s1);
        /*
             * No need to check the result size against the all-instantiated since the type count
             * didn't change.
             */
        PointsToStats.registerUnionOperation(bb, s1, s2, result);
        return result;
    } else {
        AnalysisObject[] resultObjects;
        if (s2.exactType().getId() < s1.firstType().getId()) {
            resultObjects = TypeStateUtils.concat(s2.objects, s1.objects);
        } else if (s2.exactType().getId() > s1.lastType().getId()) {
            resultObjects = TypeStateUtils.concat(s1.objects, s2.objects);
        } else {
            /* Find insertion point within the s1.objects. */
            int idx1 = 0;
            while (idx1 < s1.objects.length && s1.objects[idx1].type().getId() < s2.exactType().getId()) {
                idx1++;
            }
            /* Create the resulting objects array and insert the s2 objects. */
            resultObjects = new AnalysisObject[s1.objects.length + s2.objects.length];
            System.arraycopy(s1.objects, 0, resultObjects, 0, idx1);
            System.arraycopy(s2.objects, 0, resultObjects, idx1, s2.objects.length);
            System.arraycopy(s1.objects, idx1, resultObjects, idx1 + s2.objects.length, s1.objects.length - idx1);
        }
        /* Create the types bit set by adding the s2 type to avoid walking the objects. */
        BitSet typesBitSet = TypeStateUtils.set(s1.typesBitSet, s2.exactType().getId());
        int properties = bb.analysisPolicy().makePopertiesForUnion(s1, s2);
        MultiTypeState result = new MultiTypeState(bb, resultCanBeNull, properties, typesBitSet, resultObjects);
        PointsToStats.registerUnionOperation(bb, s1, s2, result);
        return result;
    }
}
Also used : AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject) BitSet(java.util.BitSet) Range(com.oracle.graal.pointsto.typestate.MultiTypeState.Range)

Example 2 with Range

use of com.oracle.graal.pointsto.typestate.MultiTypeState.Range in project graal by oracle.

the class UnknownTypeState method doSubtraction.

private static TypeState doSubtraction(BigBang bb, MultiTypeState s1, SingleTypeState s2) {
    boolean resultCanBeNull = s1.canBeNull() && !s2.canBeNull();
    if (s1.containsType(s2.exactType())) {
        /* See comment above for the limitation explanation. */
        assert s2.objects.length == 1 && s2.objects[0].isContextInsensitiveObject() : "Current implementation limitation.";
        /* Find the range of objects of s2.exactType() in s1. */
        Range typeRange = s1.findTypeRange(s2.exactType());
        int newLength = s1.objects.length - (typeRange.right - typeRange.left);
        AnalysisObject[] resultObjects = new AnalysisObject[newLength];
        /* Copy all the objects in s1 but the ones inside the range to the result list. */
        System.arraycopy(s1.objects, 0, resultObjects, 0, typeRange.left);
        System.arraycopy(s1.objects, typeRange.right, resultObjects, typeRange.left, s1.objects.length - typeRange.right);
        if (resultObjects.length == 1) {
            return new SingleTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, resultObjects[0]), resultObjects[0]);
        } else if (TypeStateUtils.holdsSingleTypeState(resultObjects)) {
            /* Multiple objects of the same type. */
            return new SingleTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, resultObjects), resultObjects);
        } else {
            BitSet resultTypesBitSet = TypeStateUtils.clear(s1.typesBitSet, s2.exactType().getId());
            return new MultiTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, resultObjects), resultTypesBitSet, resultObjects);
        }
    } else {
        return s1.forCanBeNull(bb, resultCanBeNull);
    }
}
Also used : AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject) BitSet(java.util.BitSet) Range(com.oracle.graal.pointsto.typestate.MultiTypeState.Range)

Aggregations

AnalysisObject (com.oracle.graal.pointsto.flow.context.object.AnalysisObject)2 Range (com.oracle.graal.pointsto.typestate.MultiTypeState.Range)2 BitSet (java.util.BitSet)2