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