use of com.oracle.graal.pointsto.flow.FieldTypeFlow in project graal by oracle.
the class JNIAccessFeature method addField.
private static void addField(Field reflField, DuringAnalysisAccessImpl access) {
BigBang bigBang = access.getBigBang();
JNIAccessibleClass jniClass = addClass(reflField.getDeclaringClass(), access);
jniClass.addFieldIfAbsent(reflField.getName(), n -> {
AnalysisField field = access.getMetaAccess().lookupJavaField(reflField);
field.registerAsAccessed();
// Same as BigBang.addSystemField() and BigBang.addSystemStaticField():
// create type flows for any subtype of the field's declared type
TypeFlow<?> declaredTypeFlow = field.getType().getTypeFlow(bigBang, true);
if (field.isStatic()) {
declaredTypeFlow.addUse(bigBang, field.getStaticFieldFlow());
} else {
FieldTypeFlow instanceFieldFlow = field.getDeclaringClass().getContextInsensitiveAnalysisObject().getInstanceFieldFlow(bigBang, field, true);
declaredTypeFlow.addUse(bigBang, instanceFieldFlow);
}
return new JNIAccessibleField(jniClass, reflField.getName(), field.getJavaKind(), field.getModifiers());
});
}
use of com.oracle.graal.pointsto.flow.FieldTypeFlow in project graal by oracle.
the class PointsToStats method asString.
private static String asString(TypeFlow<?> flow) {
if (flow instanceof AllInstantiatedTypeFlow) {
return "AllInstantiated(" + formatType(flow.getDeclaredType(), true) + ")";
} else if (flow instanceof AllSynchronizedTypeFlow) {
return "AllSynchronized";
} else if (flow instanceof UnknownTypeFlow) {
return "Unknown";
} else if (flow instanceof FieldSinkTypeFlow) {
FieldSinkTypeFlow sink = (FieldSinkTypeFlow) flow;
return "FieldSink(" + formatField(sink.getSource()) + ")";
} else if (flow instanceof FieldTypeFlow) {
FieldTypeFlow fieldFlow = (FieldTypeFlow) flow;
AnalysisField field = fieldFlow.getSource();
return (field.isStatic() ? "StaticField" : "InstanceField") + "(" + formatField(field) + ")";
} else if (flow instanceof StoreInstanceFieldTypeFlow) {
StoreInstanceFieldTypeFlow store = (StoreInstanceFieldTypeFlow) flow;
return "InstanceStore(" + formatField(store.field()) + ")@" + formatSource(flow);
} else if (flow instanceof StoreStaticFieldTypeFlow) {
StoreStaticFieldTypeFlow store = (StoreStaticFieldTypeFlow) flow;
return "StaticStore(" + formatField(store.field()) + ")@" + formatSource(flow);
} else if (flow instanceof LoadInstanceFieldTypeFlow) {
LoadInstanceFieldTypeFlow load = (LoadInstanceFieldTypeFlow) flow;
return "InstanceLoad(" + formatField(load.field()) + ")@" + formatSource(flow);
} else if (flow instanceof LoadStaticFieldTypeFlow) {
LoadStaticFieldTypeFlow load = (LoadStaticFieldTypeFlow) flow;
return "StaticLoad(" + formatField(load.field()) + ")@" + formatSource(flow);
} else if (flow instanceof StoreIndexedTypeFlow) {
return "IndexedStore @ " + formatSource(flow);
} else if (flow instanceof UnsafeStoreTypeFlow) {
return "UnsafeStore @ " + formatSource(flow);
} else if (flow instanceof UnsafePartitionStoreTypeFlow) {
return "UnsafePartitionStore @ " + formatSource(flow);
} else if (flow instanceof UnsafeWriteSinkTypeFlow) {
UnsafeWriteSinkTypeFlow sink = (UnsafeWriteSinkTypeFlow) flow;
return "UnsafeWriteSink(" + formatField(sink.getSource()) + ")";
} else if (flow instanceof JavaWriteTypeFlow) {
return "JavaWrite @ " + formatSource(flow);
} else if (flow instanceof AtomicWriteTypeFlow) {
return "AtomicWrite @ " + formatSource(flow);
} else if (flow instanceof CompareAndSwapTypeFlow) {
return "CompareAndSwap @ " + formatSource(flow);
} else if (flow instanceof LoadIndexedTypeFlow) {
return "IndexedLoad @ " + formatSource(flow);
} else if (flow instanceof UnsafeLoadTypeFlow) {
return "UnsafeLoad @ " + formatSource(flow);
} else if (flow instanceof UnsafePartitionLoadTypeFlow) {
return "UnsafePartitionLoad @ " + formatSource(flow);
} else if (flow instanceof JavaReadTypeFlow) {
return "JavaRead @ " + formatSource(flow);
} else if (flow instanceof AtomicReadTypeFlow) {
return "AtomicRead @ " + formatSource(flow);
} else if (flow instanceof ArrayElementsTypeFlow) {
ArrayElementsTypeFlow arrayFlow = (ArrayElementsTypeFlow) flow;
return "ArrayElements(" + (arrayFlow.object() != null ? arrayFlow.object().type().toJavaName(false) : "?") + ")";
} else if (flow instanceof NullCheckTypeFlow) {
NullCheckTypeFlow nullCheck = (NullCheckTypeFlow) flow;
return "NullCheck(" + (nullCheck.isFilterNull() ? "not-null" : "only-null") + ")@" + formatSource(flow);
} else if (flow instanceof FilterTypeFlow) {
FilterTypeFlow filter = (FilterTypeFlow) flow;
String properties = filter.isExact() ? "exact" : "not-exact";
properties += ", " + (filter.isAssignable() ? "assignable" : "not-assignable");
properties += ", " + (filter.includeNull() ? "include-null" : "not-include-null");
return "Filter(" + properties + ", " + formatType(filter.getType(), true) + ")@" + formatSource(flow);
} else if (flow instanceof FieldFilterTypeFlow) {
FieldFilterTypeFlow filter = (FieldFilterTypeFlow) flow;
return "FieldFilter(" + formatField(filter.getSource()) + ")";
} else if (flow instanceof FrozenFieldFilterTypeFlow) {
FrozenFieldFilterTypeFlow filter = (FrozenFieldFilterTypeFlow) flow;
return "FrozenFieldFilter(" + formatField(filter.getSource()) + ")";
} else if (flow instanceof InstanceOfTypeFlow) {
InstanceOfTypeFlow instanceOf = (InstanceOfTypeFlow) flow;
return "InstanceOf(" + formatType(instanceOf.getDeclaredType(), true) + ")@" + formatSource(flow);
} else if (flow instanceof NewInstanceTypeFlow) {
return "NewInstance(" + flow.getDeclaredType().toJavaName(false) + ")@" + formatSource(flow);
} else if (flow instanceof DynamicNewInstanceTypeFlow) {
return "DynamicNewInstance @ " + formatSource(flow);
} else if (flow instanceof InvokeTypeFlow) {
InvokeTypeFlow invoke = (InvokeTypeFlow) flow;
return "Invoke(" + formatMethod(invoke.getTargetMethod()) + ")@" + formatSource(flow);
} else if (flow instanceof InitialParamTypeFlow) {
InitialParamTypeFlow param = (InitialParamTypeFlow) flow;
return "InitialParam(" + param.position() + ")@" + formatMethod(param.method());
} else if (flow instanceof FormalParamTypeFlow) {
FormalParamTypeFlow param = (FormalParamTypeFlow) flow;
return "Parameter(" + param.position() + ")@" + formatMethod(param.method());
} else if (flow instanceof FormalReturnTypeFlow) {
return "Return @ " + formatSource(flow);
} else if (flow instanceof ActualReturnTypeFlow) {
ActualReturnTypeFlow ret = (ActualReturnTypeFlow) flow;
InvokeTypeFlow invoke = ret.invokeFlow();
return "ActualReturn(" + formatMethod(invoke.getTargetMethod()) + ")@ " + formatSource(flow);
} else if (flow instanceof MergeTypeFlow) {
return "Merge @ " + formatSource(flow);
} else if (flow instanceof SourceTypeFlow) {
return "Source @ " + formatSource(flow);
} else if (flow instanceof CloneTypeFlow) {
return "Clone @ " + formatSource(flow);
} else if (flow instanceof MonitorEnterTypeFlow) {
MonitorEnterTypeFlow monitor = (MonitorEnterTypeFlow) flow;
return "MonitorEnter @ " + formatMethod(monitor.getMethod());
} else {
return flow.getClass().getSimpleName() + "@" + formatSource(flow);
}
}
use of com.oracle.graal.pointsto.flow.FieldTypeFlow in project graal by oracle.
the class ContextSensitiveAnalysisObject method getReferencedObjects.
/**
* Returns the list of referenced objects, i.e., field objects or array elements 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<AnalysisObject> getReferencedObjects() {
if (referencedObjects == null) {
// TODO do we need to materialize the objects in a HashSet here, or could we just
// iterate over them?
HashSet<AnalysisObject> objectsSet = new HashSet<>();
if (this.type().isArray()) {
for (AnalysisObject object : arrayElementsTypeStore.readFlow().getState().objects()) {
objectsSet.add(object);
}
} else {
if (instanceFieldsTypeStore != null) {
for (int i = 0; i < instanceFieldsTypeStore.length(); i++) {
FieldTypeStore fieldTypeStore = instanceFieldsTypeStore.get(i);
if (fieldTypeStore != null) {
FieldTypeFlow fieldFlow = ((UnifiedFieldTypeStore) fieldTypeStore).readWriteFlow();
if (!fieldFlow.getState().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 (AnalysisObject object : fieldFlow.getState().objects()) {
objectsSet.add(object);
}
}
}
}
}
}
referencedObjects = new ArrayList<>(objectsSet);
}
return referencedObjects;
}
use of com.oracle.graal.pointsto.flow.FieldTypeFlow in project graal by oracle.
the class ContextSensitiveAnalysisObject method mergeInstanceFieldFlow.
/**
* Merge the read and write flows of the fieldTypeStore with those of the context insensitive
* object.
*/
private static void mergeInstanceFieldFlow(BigBang bb, FieldTypeStore fieldTypeStore, AnalysisObject object) {
AnalysisField field = fieldTypeStore.field();
FieldTypeFlow readFieldFlow = fieldTypeStore.readFlow();
FieldTypeFlow writeFieldFlow = fieldTypeStore.writeFlow();
FieldTypeFlow parentWriteFieldFlow = object.getInstanceFieldFlow(bb, field, true);
FieldTypeFlow parentReadFieldFlow = object.getInstanceFieldFlow(bb, field, false);
parentWriteFieldFlow.addUse(bb, writeFieldFlow);
readFieldFlow.addUse(bb, parentReadFieldFlow);
}
use of com.oracle.graal.pointsto.flow.FieldTypeFlow in project graal by oracle.
the class AnalysisObjectScanner method forNonNullFieldValue.
@Override
public void forNonNullFieldValue(JavaConstant receiver, AnalysisField field, JavaConstant fieldValue) {
AnalysisType fieldType = bb.getMetaAccess().lookupJavaType(bb.getSnippetReflectionProvider().asObject(Object.class, fieldValue).getClass());
assert fieldType.isInstantiated();
if (bb.getAllInstantiatedTypeFlow().getState().containsType(fieldType)) {
/* Add the constant value object to the field's type flow. */
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver);
AnalysisObject constantObject = bb.analysisPolicy().createConstantObject(bb, fieldValue, fieldType);
if (!fieldTypeFlow.getState().isUnknown() && !fieldTypeFlow.getState().containsObject(constantObject)) {
/* Add the new constant to the field's flow state. */
TypeState constantTypeState = TypeState.forNonNullObject(bb, constantObject);
fieldTypeFlow.addState(bb, constantTypeState);
}
}
}
Aggregations