@Override public void init(BigBang bb) { /* * For split field stores we link the write flows to the read flows, such that all the * stores in the write partition can be loaded from the read partition. Done lazily because * these type stores are created concurrently. */ writeFlow.addUse(bb, readFlow); }
public SplitFieldTypeStore(AnalysisField field, AnalysisObject object) { super(field, object); this.writeFlow = new FieldTypeFlow(field, field.getType(), object); this.readFlow = new FieldTypeFlow(field, field.getType(), object); }
@Override public String toString() { return "FieldFlow<" + source.format("%h.%n") + "\n" + getState() + ">"; }
public FieldTypeFlow(AnalysisField field, AnalysisType type) { super(field, type, initialFieldState(field)); }
} 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) {
/** * Returns all possible types that this field can have. The result is not context sensitive, * i.e., it is a union of all types found in all contexts. */ public TypeState getTypeState() { if (getType().getStorageKind() != JavaKind.Object) { return null; } else if (isStatic()) { return staticFieldFlow.getState(); } else { return getInstanceFieldTypeState(); } }
@Override public void initClone(BigBang bb) { fieldFlow.addUse(bb, this); }
@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(); /* * *ALL* constants are scanned after each analysis iteration, thus the fieldType will * eventually be added to the AllInstantiatedTypeFlow and the field type flow will * eventually be updated. */ 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); } } }
public UnifiedFieldTypeStore(AnalysisField field, AnalysisObject object) { super(field, object); this.readWriteFlow = new FieldTypeFlow(field, field.getType(), object); }
/** * 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); }
public AnalysisField(AnalysisUniverse universe, ResolvedJavaField wrappedField) { assert !wrappedField.isInternal(); this.position = -1; this.isUnsafeAccessed = new AtomicBoolean(); this.unsafeFrozenTypeState = new AtomicBoolean(); this.wrapped = wrappedField; this.id = universe.nextFieldId.getAndIncrement(); readBy = PointstoOptions.TrackAccessChain.getValue(universe.hostVM().options()) ? new ConcurrentHashMap<>() : null; writtenBy = new ConcurrentHashMap<>(); declaringClass = universe.lookup(wrappedField.getDeclaringClass()); fieldType = getDeclaredType(universe, wrappedField); isUsedInComparison = false; if (this.isStatic()) { this.canBeNull = false; this.staticFieldFlow = new FieldTypeFlow(this, getType()); this.initialInstanceFieldFlow = null; } else { this.canBeNull = true; this.instanceFieldFlow = new FieldSinkTypeFlow(this, getType()); this.initialInstanceFieldFlow = new FieldTypeFlow(this, getType()); } }
protected final FieldTypeStore getInstanceFieldTypeStore(BigBang bb, AnalysisField field) { assert !Modifier.isStatic(field.getModifiers()); assert bb != null && !bb.getUniverse().sealed(); if (instanceFieldsTypeStore == null) { AnalysisField[] fields = type.getInstanceFields(true); INSTANCE_FIELD_TYPE_STORE_UPDATER.compareAndSet(this, null, new AtomicReferenceArray<>(fields.length)); } FieldTypeStore fieldStore = instanceFieldsTypeStore.get(field.getPosition()); if (fieldStore == null) { fieldStore = bb.analysisPolicy().createFieldTypeStore(this, field, bb.getUniverse()); boolean result = instanceFieldsTypeStore.compareAndSet(field.getPosition(), null, fieldStore); if (result) { fieldStore.init(bb); // link the initial instance field flow to the field write flow field.getInitialInstanceFieldFlow().addUse(bb, fieldStore.writeFlow()); // link the field read flow to the context insensitive instance field flow fieldStore.readFlow().addUse(bb, field.getInstanceFieldFlow()); } else { fieldStore = instanceFieldsTypeStore.get(field.getPosition()); } } return fieldStore; }
@Override public void onObservedUpdate(BigBang bb) { /* Only a clone should be updated */ assert this.isClone(); /* * The state of the receiver object of the load operation has changed. Link the new heap * sensitive field flows. */ TypeState objectState = objectFlow.getState(); if (objectState.isUnknown()) { bb.reportIllegalUnknownUse(graphRef.getMethod(), source, "Illegal: Field loading from UnknownTypeState objects. Field: " + field); return; } /* Iterate over the receiver objects. */ for (AnalysisObject object : objectState.objects()) { /* Get the field flow corresponding to the receiver object. */ FieldTypeFlow fieldFlow = object.getInstanceFieldFlow(bb, field, false); /* Add the load field flow as a use to the heap sensitive field flow. */ fieldFlow.addUse(bb, this); } }
if (fieldDeclaredType.isArray()) { AnalysisType fieldComponentType = fieldDeclaredType.getComponentType(); aField.getInitialInstanceFieldFlow().addUse(this, aField.getInstanceFieldFlow());
originalObjectFieldFlow.addUse(bb, cloneObjectFieldFlow);