Search in sources :

Example 1 with AnalysisObject

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

the class NewInstanceTypeFlow method createHeapObject.

private AnalysisObject createHeapObject(BigBang bb, AnalysisContext objContext) {
    assert !this.isClone();
    if (heapObjectsCache == null) {
        /* Lazily initialize the cache. */
        HEAP_OBJECTS_CACHE_UPDATER.compareAndSet(this, null, new ConcurrentHashMap<>());
    }
    AnalysisObject result = heapObjectsCache.get(objContext);
    if (result == null) {
        AnalysisObject newValue = bb.analysisPolicy().createHeapObject(bb, type, allocationSite, objContext);
        AnalysisObject oldValue = heapObjectsCache.putIfAbsent(objContext, newValue);
        result = oldValue != null ? oldValue : newValue;
    }
    return result;
}
Also used : AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject)

Example 2 with AnalysisObject

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

the class CloneTypeFlow method update.

@Override
public void update(BigBang bb) {
    assert this.isClone();
    TypeState inputState = input.getState();
    TypeState cloneState = this.getState();
    for (AnalysisType type : inputState.types()) {
        if (type.isArray()) {
            /* The object array clones must also get the elements flows of the originals. */
            for (AnalysisObject originalObject : inputState.objects(type)) {
                if (originalObject.isPrimitiveArray() || originalObject.isEmptyObjectArrayConstant(bb)) {
                    /* Nothing to read from a primitive array or an empty array constant. */
                    continue;
                }
                ArrayElementsTypeFlow originalObjectElementsFlow = originalObject.getArrayElementsFlow(bb, false);
                for (AnalysisObject cloneObject : cloneState.objects(type)) {
                    if (cloneObject.isPrimitiveArray() || cloneObject.isEmptyObjectArrayConstant(bb)) {
                        /* Cannot write to a primitive array or an empty array constant. */
                        continue;
                    }
                    ArrayElementsTypeFlow cloneObjectElementsFlow = cloneObject.getArrayElementsFlow(bb, true);
                    originalObjectElementsFlow.addUse(bb, cloneObjectElementsFlow);
                }
            }
        } else {
            /* The object clones must get field flows of the originals. */
            for (AnalysisObject originalObject : inputState.objects(type)) {
                /* Link all the field flows of the original to the clone. */
                for (AnalysisField field : type.getInstanceFields(true)) {
                    FieldTypeFlow originalObjectFieldFlow = originalObject.getInstanceFieldFlow(bb, field, false);
                    for (AnalysisObject cloneObject : cloneState.objects(type)) {
                        FieldTypeFlow cloneObjectFieldFlow = cloneObject.getInstanceFieldFlow(bb, field, true);
                        originalObjectFieldFlow.addUse(bb, cloneObjectFieldFlow);
                    }
                }
            }
        }
    }
    /* Element flows of array clones (if any) have been updated, update the uses. */
    super.update(bb);
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject) TypeState(com.oracle.graal.pointsto.typestate.TypeState) AnalysisField(com.oracle.graal.pointsto.meta.AnalysisField)

Example 3 with AnalysisObject

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

the class AnalysisObjectScanner method forNonNullArrayElement.

@Override
public void forNonNullArrayElement(JavaConstant array, AnalysisType arrayType, JavaConstant elementConstant, AnalysisType elementType, int elementIndex) {
    assert elementType.isInstantiated();
    /*
         * *ALL* constants are scanned after each analysis iteration, thus the elementType will
         * eventually be added to the AllInstantiatedTypeFlow and the array elements flow will
         * eventually be updated.
         */
    if (bb.getAllInstantiatedTypeFlow().getState().containsType(elementType)) {
        ArrayElementsTypeFlow arrayObjElementsFlow = getArrayElementsFlow(array, arrayType);
        AnalysisObject constantObject = bb.analysisPolicy().createConstantObject(bb, elementConstant, elementType);
        if (!arrayObjElementsFlow.getState().isUnknown() && !arrayObjElementsFlow.getState().containsObject(constantObject)) {
            /* Add the constant element to the constant's array type flow. */
            TypeState elementTypeState = TypeState.forNonNullObject(bb, constantObject);
            arrayObjElementsFlow.addState(bb, elementTypeState);
        }
    }
}
Also used : ArrayElementsTypeFlow(com.oracle.graal.pointsto.flow.ArrayElementsTypeFlow) AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject) TypeState(com.oracle.graal.pointsto.typestate.TypeState)

Example 4 with AnalysisObject

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

the class UnknownTypeState method doSubtraction1.

private static TypeState doSubtraction1(BigBang bb, MultiTypeState s1, MultiTypeState s2, boolean resultCanBeNull) {
    /*
         * Speculate that s1 and s2 have no overlap, i.e., they don't have any objects in common. In
         * that case, the result is just s1.
         */
    int idx1 = 0;
    int idx2 = 0;
    while (true) {
        AnalysisObject o1 = s1.objects[idx1];
        AnalysisObject o2 = s2.objects[idx2];
        /* See comment above for the limitation explanation. */
        assert o2.isContextInsensitiveObject() : "Current implementation limitation.";
        if (o1.type().getId() < o2.type().getId()) {
            idx1++;
            if (idx1 == s1.objects.length) {
                return s1.forCanBeNull(bb, resultCanBeNull);
            }
        } else if (o1.type().getId() > o2.type().getId()) {
            idx2++;
            if (idx2 == s2.objects.length) {
                return s1.forCanBeNull(bb, resultCanBeNull);
            }
        } else {
            /* Our speculation failed. */
            break;
        }
    }
    return doSubtraction2(bb, s1, s2, resultCanBeNull, idx1, idx2);
}
Also used : AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject)

Example 5 with AnalysisObject

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

the class UnknownTypeState method doSubtraction2.

private static TypeState doSubtraction2(BigBang bb, MultiTypeState s1, MultiTypeState s2, boolean resultCanBeNull, int idx1Param, int idx2Param) {
    int idx1 = idx1Param;
    int idx2 = idx2Param;
    UnsafeArrayList<AnalysisObject> resultObjects = new UnsafeArrayList<>(new AnalysisObject[s1.objects.length]);
    resultObjects.addAll(s1.objects, 0, idx1);
    while (idx1 < s1.objects.length && idx2 < s2.objects.length) {
        AnalysisObject o1 = s1.objects[idx1];
        AnalysisObject o2 = s2.objects[idx2];
        /* See comment above for the limitation explanation. */
        assert o2.isContextInsensitiveObject() : "Current implementation limitation.";
        if (o1.type().getId() < o2.type().getId()) {
            resultObjects.add(o1);
            idx1++;
        } else if (o1.type().getId() > o2.type().getId()) {
            idx2++;
        } else {
            assert o1.type().equals(o2.type());
            while (idx1 < s1.objects.length && s1.objects[idx1].type().equals(o2.type())) {
                /* Walk over the s1 objects of the same type, they are eliminated. */
                idx1++;
            }
            idx2++;
        }
    }
    if (idx1 < s1.objects.length) {
        resultObjects.addAll(s1.objects, idx1, s1.objects.length);
    }
    if (resultObjects.size() == 0) {
        return TypeState.forEmpty().forCanBeNull(bb, resultCanBeNull);
    } else if (TypeStateUtils.holdsSingleTypeState(resultObjects.elementData, resultObjects.size)) {
        /* Multiple objects of the same type. */
        AnalysisObject[] objects = resultObjects.copyToArray(new AnalysisObject[resultObjects.size()]);
        return new SingleTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, objects), objects);
    } else {
        BitSet resultTypesBitSet = TypeStateUtils.andNot(s1.typesBitSet, s2.typesBitSet);
        /* Don't need to check if the result is close-to-all-instantiated since result <= s1. */
        AnalysisObject[] objects = resultObjects.copyToArray(new AnalysisObject[resultObjects.size()]);
        return new MultiTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, objects), resultTypesBitSet, objects);
    }
}
Also used : AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject) BitSet(java.util.BitSet)

Aggregations

AnalysisObject (com.oracle.graal.pointsto.flow.context.object.AnalysisObject)24 BitSet (java.util.BitSet)8 TypeState (com.oracle.graal.pointsto.typestate.TypeState)5 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)4 AnalysisContext (com.oracle.graal.pointsto.flow.context.AnalysisContext)2 Range (com.oracle.graal.pointsto.typestate.MultiTypeState.Range)2 ArrayElementsTypeFlow (com.oracle.graal.pointsto.flow.ArrayElementsTypeFlow)1 FieldTypeFlow (com.oracle.graal.pointsto.flow.FieldTypeFlow)1 ConstantContextSensitiveObject (com.oracle.graal.pointsto.flow.context.object.ConstantContextSensitiveObject)1 AnalysisField (com.oracle.graal.pointsto.meta.AnalysisField)1 ArrayList (java.util.ArrayList)1 PrimitiveConstant (jdk.vm.ci.meta.PrimitiveConstant)1 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)1