use of com.oracle.graal.pointsto.typestate.TypeState 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.typestate.TypeState in project graal by oracle.
the class FrozenFieldFilterTypeFlow method filter.
@Override
public TypeState filter(BigBang bb, TypeState update) {
/*
* Filter using the current type state of the field, i.e., the type state constructed
* through normal writes and non frozen unsafe writes, if any.
*/
TypeState fieldState = this.source.getInstanceFieldFlow().getState();
/*
* Strip the context, if any, of the field state.
*/
TypeState filter = TypeState.forContextInsensitiveTypeState(bb, fieldState);
return TypeState.forIntersection(bb, update, filter);
}
use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.
the class AnalysisType method updateTypeFlows.
/**
* Called when the list of assignable types of a type is first initialized.
*/
private void updateTypeFlows(BigBang bb, TypeFlow<?> assignable, TypeFlow<?> assignableNonNull) {
if (isPrimitive() || isJavaLangObject()) {
return;
}
AnalysisType superType;
if (isInterface()) {
/*
* For interfaces, we have to search all instantiated types, i.e., start at
* java.lang.Object
*/
superType = bb.getObjectType();
} else {
/*
* Find the closest supertype that has assignable-information computed. That is the best
* starting point.
*/
superType = getSuperclass();
while (superType.assignableTypes == null) {
superType = superType.getSuperclass();
}
}
TypeState superAssignableTypeState = superType.assignableTypes.getState();
BitSet assignableTypesSet = new BitSet();
for (AnalysisType type : superAssignableTypeState.types()) {
if (this.isAssignableFrom(type)) {
assignableTypesSet.set(type.getId());
}
}
TypeState assignableTypeState = TypeState.forExactTypes(bb, assignableTypesSet, true);
updateFlow(bb, assignable, assignableTypeState);
updateFlow(bb, assignableNonNull, assignableTypeState.forNonNull(bb));
}
use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.
the class AnalysisType method getReferencedTypes.
/**
* Returns the list of referenced types, i.e., concrete field types or array elements types
* discovered by the static analysis.
*
* Since this list is not updated during the analysis, for complete results this should only be
* called when the base analysis has finished.
*/
public List<AnalysisType> getReferencedTypes(BigBang bb) {
if (referencedTypes == null) {
Set<AnalysisType> referencedTypesSet = new HashSet<>();
if (this.isArray()) {
if (this.getContextInsensitiveAnalysisObject().isObjectArray()) {
/* Collect the types referenced through index store (for arrays). */
for (AnalysisType type : getContextInsensitiveAnalysisObject().getArrayElementsFlow(bb, false).getState().types()) {
/* Add the assignable types, as discovered by the static analysis. */
type.getTypeFlow(bb, false).getState().types().forEach(referencedTypesSet::add);
}
}
} else {
/* Collect the field referenced types. */
for (AnalysisField field : getInstanceFields(true)) {
TypeState state = field.getInstanceFieldTypeState();
if (!state.isUnknown()) {
/*
* If the field state is unknown we don't process the state. Unknown means
* that the state can contain any object of any type, but the core analysis
* guarantees that there is no path on which the objects of an unknown type
* state are converted to and used as java objects; they are just used as
* data.
*/
for (AnalysisType type : state.types()) {
/* Add the assignable types, as discovered by the static analysis. */
type.getTypeFlow(bb, false).getState().types().forEach(referencedTypesSet::add);
}
}
}
}
referencedTypes = new ArrayList<>(referencedTypesSet);
}
return referencedTypes;
}
use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.
the class AnalysisType method updateAssignableTypes.
public static void updateAssignableTypes(BigBang bb) {
/*
* Update the assignable-state for all types. So do not post any update operations before
* the computation is finished, because update operations must not see any intermediate
* state.
*/
List<AnalysisType> allTypes = bb.getUniverse().getTypes();
List<TypeFlow<?>> changedFlows = new ArrayList<>();
Map<Integer, BitSet> newAssignableTypes = new HashMap<>();
for (AnalysisType type : allTypes) {
if (type.isInstantiated()) {
int arrayDimension = 0;
AnalysisType elementalType = type;
while (elementalType.isArray()) {
elementalType = elementalType.getComponentType();
arrayDimension++;
}
addTypeToAssignableLists(type.getId(), elementalType, arrayDimension, newAssignableTypes, true, bb);
if (arrayDimension > 0) {
addTypeToAssignableLists(type.getId(), type, 0, newAssignableTypes, true, bb);
}
for (int i = 0; i < arrayDimension; i++) {
addTypeToAssignableLists(type.getId(), bb.getObjectType(), i, newAssignableTypes, false, bb);
}
if (!elementalType.isPrimitive()) {
addTypeToAssignableLists(type.getId(), bb.getObjectType(), arrayDimension, newAssignableTypes, false, bb);
}
}
}
for (AnalysisType type : allTypes) {
if (type.assignableTypes != null) {
TypeState assignableTypeState = TypeState.forNull();
if (newAssignableTypes.get(type.getId()) != null) {
BitSet assignableTypes = newAssignableTypes.get(type.getId());
if (type.assignableTypes.getState().hasExactTypes(assignableTypes)) {
/* Avoid creation of the expensive type state. */
continue;
}
assignableTypeState = TypeState.forExactTypes(bb, newAssignableTypes.get(type.getId()), true);
}
updateFlow(bb, type.assignableTypes, assignableTypeState, changedFlows);
updateFlow(bb, type.assignableTypesNonNull, assignableTypeState.forNonNull(bb), changedFlows);
}
}
for (TypeFlow<?> changedFlow : changedFlows) {
bb.postFlow(changedFlow);
}
}
Aggregations