/** Adds a use, if not already present, without propagating state. */ public boolean addOriginalUse(BigBang bb, TypeFlow<?> use) { return addUse(bb, use, false, false); }
public boolean addUse(BigBang bb, TypeFlow<?> use) { return addUse(bb, use, true, false); }
@Override public void initClone(BigBang bb) { assert this.isClone(); this.input.addUse(bb, this); }
public void setInitialParameterFlow(BigBang bb, AnalysisType declaredType, int i) { TypeFlow<?> declaredTypeFlow = declaredType.getTypeFlow(bb, true); InitialParamTypeFlow initialParameterFlow = new InitialParamTypeFlow(method, declaredType, i); declaredTypeFlow.addUse(bb, initialParameterFlow); originalMethodFlows.setInitialParameterFlow(initialParameterFlow, i); }
public void setInitialReceiverFlow(BigBang bb, AnalysisType declaringType) { TypeFlow<?> declaringTypeFlow = declaringType.getTypeFlow(bb, false); InitialReceiverTypeFlow initialReceiverFlow = new InitialReceiverTypeFlow(method, declaringType); declaringTypeFlow.addUse(bb, initialReceiverFlow); originalMethodFlows.setInitialParameterFlow(initialReceiverFlow, 0); }
@SuppressWarnings("try") public AnalysisType addSystemStaticField(Class<?> clazz, String fieldName) { addSystemClass(clazz, false, false); Field reflectField; try { try (Indent indent = debug.logAndIndent("add system static field %s in class %s", fieldName, clazz.getName())) { reflectField = clazz.getField(fieldName); AnalysisField field = metaAccess.lookupJavaField(reflectField); field.registerAsAccessed(); TypeFlow<?> fieldFlow = field.getType().getTypeFlow(this, true); fieldFlow.addUse(this, field.getStaticFieldFlow()); return field.getType(); } } catch (NoSuchFieldException e) { throw shouldNotReachHere("field not found: " + fieldName); } }
@SuppressWarnings("try") public AnalysisType addSystemField(Class<?> clazz, String fieldName) { AnalysisType type = addSystemClass(clazz, false, false); for (AnalysisField field : type.getInstanceFields(true)) { if (field.getName().equals(fieldName)) { try (Indent indent = debug.logAndIndent("add system field %s in class %s", fieldName, clazz.getName())) { field.registerAsAccessed(); /* * For system classes any instantiated (sub)type of the declared field type can * be written to the field flow. */ TypeFlow<?> fieldDeclaredTypeFlow = field.getType().getTypeFlow(this, true); fieldDeclaredTypeFlow.addUse(this, type.getContextInsensitiveAnalysisObject().getInstanceFieldFlow(this, field, true)); } return field.getType(); } } throw shouldNotReachHere("field not found: " + fieldName); }
private static void addField(Field reflField, boolean writable, DuringAnalysisAccessImpl access) { BigBang bigBang = access.getBigBang(); JNIAccessibleClass jniClass = addClass(reflField.getDeclaringClass(), access); AnalysisField field = access.getMetaAccess().lookupJavaField(reflField); jniClass.addFieldIfAbsent(field.getName(), name -> new JNIAccessibleField(jniClass, name, field.getJavaKind(), field.getModifiers())); field.registerAsRead(null); if (writable) { field.registerAsWritten(null); } else if (field.isStatic() && field.isFinal()) { MaterializedConstantFields.singleton().register(field); } // 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, writable); declaredTypeFlow.addUse(bigBang, instanceFieldFlow); } }
TypeFlow<?> fieldDeclaredTypeFlow = fieldDeclaredType.getTypeFlow(this, true); if (aField.isStatic()) { fieldDeclaredTypeFlow.addUse(this, aField.getStaticFieldFlow()); } else { fieldDeclaredTypeFlow.addUse(this, aField.getInitialInstanceFieldFlow()); if (fieldDeclaredType.isArray()) { AnalysisType fieldComponentType = fieldDeclaredType.getComponentType();
@SuppressWarnings({"try"}) private AnalysisType addSystemClass(AnalysisType type, boolean addFields, boolean addArrayClass) { try (Indent indent = debug.logAndIndent("add system class %s", type.getName())) { for (AnalysisField field : type.getInstanceFields(false)) { if (addFields) { field.registerAsAccessed(); } /* * For system classes any instantiated (sub)type of the declared field type can be * written to the field flow. */ TypeFlow<?> fieldDeclaredTypeFlow = field.getType().getTypeFlow(this, true); fieldDeclaredTypeFlow.addUse(this, type.getContextInsensitiveAnalysisObject().getInstanceFieldFlow(this, field, true)); } if (type.getSuperclass() != null) { addSystemClass(type.getSuperclass(), addFields, addArrayClass); } if (addArrayClass) { addSystemClass(type.getArrayClass(), false, false); } } return type; }
@Override public void onObservedUpdate(BigBang bb) { /* Only a clone should be updated */ assert this.isClone(); TypeState objectState = getObjectState(); if (objectState.isUnknown()) { bb.reportIllegalUnknownUse(graphRef.getMethod(), source, "Illegal: Unsafe loading from UnknownTypeState. Load: " + source); return; } for (AnalysisObject object : objectState.objects()) { AnalysisType objectType = object.type(); assert !objectType.isArray(); for (AnalysisField field : objectType.unsafeAccessedFields(partitionKind)) { TypeFlow<?> fieldFlow = object.getInstanceFieldFlow(bb, field, false); if (fieldFlow.getState().isUnknown()) { bb.getUnsupportedFeatures().addMessage(graphRef.getMethod().format("%H.%n(%p)"), graphRef.getMethod(), "Illegal: Unsafe loading UnknownTypeState from object. Load: " + this.getSource()); return; } fieldFlow.addUse(bb, this); } } }
@Override public void onObservedUpdate(BigBang bb) { /* Only a clone should be updated */ assert this.isClone(); TypeState arrayState = getObjectState(); if (arrayState.isUnknown()) { bb.reportIllegalUnknownUse(graphRef.getMethod(), source, "Illegal: Index loading from UnknownTypeState. Load: " + source); return; } for (AnalysisObject object : arrayState.objects()) { if (object.isPrimitiveArray() || object.isEmptyObjectArrayConstant(bb)) { /* Nothing to read from a primitive array or an empty array constant. */ continue; } /* Add the indexed load flow as a use to the elements flow. */ TypeFlow<?> elementsFlow = object.getArrayElementsFlow(bb, false); if (elementsFlow.getState().isUnknown()) { bb.getUnsupportedFeatures().addMessage(graphRef.getMethod().format("%H.%n(%p)"), graphRef.getMethod(), "Illegal: Index loading UnknownTypeState from array. Store: " + this.getSource()); return; } elementsFlow.addUse(bb, this); } }