use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class UnknownTypeState method doUnion.
/* Implementation of union. */
private static TypeState doUnion(BigBang bb, SingleTypeState s1, SingleTypeState s2) {
if (s1.equals(s2)) {
return s1;
}
boolean resultCanBeNull = s1.canBeNull() || s2.canBeNull();
if (s1.exactType().equals(s2.exactType())) {
/* The inputs have the same type, so the result is a SingleTypeState. */
/* Create the resulting objects array. */
AnalysisObject[] resultObjects = TypeStateUtils.union(bb, s1.objects, s2.objects);
/* Check if any of the arrays contains the other. */
if (resultObjects == s1.objects) {
return s1.forCanBeNull(bb, resultCanBeNull);
} else if (resultObjects == s2.objects) {
return s2.forCanBeNull(bb, resultCanBeNull);
}
/* Due to the test above the union set cannot be equal to any of the two arrays. */
assert !PointstoOptions.ExtendedAsserts.getValue(bb.getOptions()) || !Arrays.equals(resultObjects, s1.objects) && !Arrays.equals(resultObjects, s2.objects);
/* Create the resulting exact type state. */
SingleTypeState result = new SingleTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePopertiesForUnion(s1, s2), resultObjects);
assert !s1.equals(result) && !s2.equals(result);
PointsToStats.registerUnionOperation(bb, s1, s2, result);
return result;
} else {
/* The inputs have different types, so the result is a MultiTypeState. */
AnalysisObject[] resultObjects;
if (s1.exactType().getId() < s2.exactType().getId()) {
resultObjects = TypeStateUtils.concat(s1.objects, s2.objects);
} else {
resultObjects = TypeStateUtils.concat(s2.objects, s1.objects);
}
/* We know the types, construct the types bit set without walking the objects. */
BitSet typesBitSet = new BitSet();
typesBitSet.set(s1.exactType().getId());
typesBitSet.set(s2.exactType().getId());
int properties = bb.analysisPolicy().makePopertiesForUnion(s1, s2);
TypeState result = new MultiTypeState(bb, resultCanBeNull, properties, typesBitSet, resultObjects);
PointsToStats.registerUnionOperation(bb, s1, s2, result);
return result;
}
}
use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class UnknownTypeState method doIntersection1.
private static TypeState doIntersection1(BigBang bb, MultiTypeState s1, MultiTypeState s2, boolean resultCanBeNull) {
/*
* Speculate that s2 contains all types of s1, i.e., the filter is broader than s1, thus the
* result is s1.
*/
int idx1 = 0;
int idx2 = 0;
while (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()) {
/* s2 is behind, advance s2. */
idx2++;
} else if (o1.type().getId() == o2.type().getId()) {
/* If the types are equal continue with speculation. */
while (idx1 < s1.objects.length && s1.objects[idx1].type().equals(o2.type())) {
/* Walk over the s1 objects of the same type as o2. */
idx1++;
}
idx2++;
} else {
/* Our speculation failed. */
break;
}
if (idx1 == s1.objects.length) {
return s1.forCanBeNull(bb, resultCanBeNull);
}
}
return doIntersection2(bb, s1, s2, resultCanBeNull, idx1, idx2);
}
use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class UnknownTypeState method doUnion0.
private static TypeState doUnion0(BigBang bb, MultiTypeState s1, MultiTypeState s2, boolean resultCanBeNull) {
if (s1.lastType().getId() < s2.firstType().getId()) {
/* Speculate that objects in s2 follow after objects in s1. */
/* Concatenate the objects. */
AnalysisObject[] resultObjects = TypeStateUtils.concat(s1.objects, s2.objects);
/* Logical OR the type bit sets. */
BitSet resultTypesBitSet = TypeStateUtils.or(s1.typesBitSet, s2.typesBitSet);
int properties = bb.analysisPolicy().makePopertiesForUnion(s1, s2);
MultiTypeState result = new MultiTypeState(bb, resultCanBeNull, properties, resultTypesBitSet, resultObjects);
PointsToStats.registerUnionOperation(bb, s1, s2, result);
return result;
} else if (s2.lastType().getId() < s1.firstType().getId()) {
/* Speculate that objects in s1 follow after objects in s2. */
/* Concatenate the objects. */
AnalysisObject[] resultObjects = TypeStateUtils.concat(s2.objects, s1.objects);
/* Logical OR the type bit sets. */
BitSet resultTypesBitSet = TypeStateUtils.or(s1.typesBitSet, s2.typesBitSet);
int properties = bb.analysisPolicy().makePopertiesForUnion(s1, s2);
MultiTypeState result = new MultiTypeState(bb, resultCanBeNull, properties, resultTypesBitSet, resultObjects);
PointsToStats.registerUnionOperation(bb, s1, s2, result);
return result;
}
return doUnion1(bb, s1, s2, resultCanBeNull);
}
use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class UnknownTypeState method allocationSensitiveSpeculativeUnion1.
private static TypeState allocationSensitiveSpeculativeUnion1(BigBang bb, MultiTypeState s1, MultiTypeState s2, boolean resultCanBeNull) {
int idx1 = 0;
int idx2 = 0;
while (idx1 < s1.objectsCount() && idx2 < s2.objectsCount()) {
AnalysisObject o1 = s1.objects[idx1];
AnalysisObject o2 = s2.objects[idx2];
if (bb.analysisPolicy().isSummaryObject(o1) && o1.type().equals(o2.type())) {
idx1++;
/* Skip over s2 objects of this type while marking them as merged. */
while (idx2 < s2.objectsCount() && s2.objects[idx2].type().equals(o1.type())) {
bb.analysisPolicy().noteMerge(bb, s2.objects[idx2]);
idx2++;
}
} else if (o1.getId() < o2.getId()) {
idx1++;
} else if (o1.getId() == o2.getId()) {
/* If the objects are equal continue. */
idx1++;
idx2++;
} else {
/* Our speculation failed. */
break;
}
if (idx2 == s2.objectsCount()) {
return s1.forCanBeNull(bb, resultCanBeNull);
}
}
return doUnion2(bb, s1, s2, resultCanBeNull, idx1, idx2);
}
use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class UnknownTypeState method doIntersection2.
private static TypeState doIntersection2(BigBang bb, MultiTypeState s1, MultiTypeState s2, boolean resultCanBeNull, int idx1Param, int idx2Param) {
int idx1 = idx1Param;
int idx2 = idx2Param;
try (UnsafeArrayListClosable<AnalysisObject> tlArrayClosable = getTLArrayList(intersectionArrayListTL, 256)) {
UnsafeArrayList<AnalysisObject> resultObjects = tlArrayClosable.list;
/* Add the beginning of the s1 list that we already walked above. */
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()) {
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 and add them to the result. */
resultObjects.add(s1.objects[idx1]);
idx1++;
}
idx2++;
}
}
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 {
/* Logical AND the type bit sets. */
BitSet resultTypesBitSet = TypeStateUtils.and(s1.typesBitSet, s2.typesBitSet);
AnalysisObject[] objects = resultObjects.copyToArray(new AnalysisObject[resultObjects.size()]);
MultiTypeState result = new MultiTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, objects), resultTypesBitSet, objects);
/*
* The result can be equal to s1 if and only if s1 and s2 have the same type count.
*/
if (s1.typesCount() == s2.typesCount() && result.equals(s1)) {
return s1.forCanBeNull(bb, resultCanBeNull);
}
/*
* Don't need to check if the result is close-to-all-instantiated since result <=
* s1.
*/
return result;
}
}
}
Aggregations