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;
}
}
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);
}
}
Aggregations