[ApiModel] Set api levels directly on definitions
Tracking at optimization becomes complicated when adding a NOT_SET level
since these should be canonicalized if possible. This CL moves the api
level into the definitions.
Bug: 188388130
Change-Id: Ie367c695bb9200ecc7abb94f245cc9ddec3adb86
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
index 6daff01..2b8a186 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -6,7 +6,6 @@
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.getNoKotlinInfo;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.MIN_API_LEVEL;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
@@ -17,7 +16,6 @@
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.optimize.info.DefaultFieldOptimizationInfo;
-import com.android.tools.r8.ir.optimize.info.DefaultFieldOptimizationWithMinApiInfo;
import com.android.tools.r8.ir.optimize.info.FieldOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.MutableFieldOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
@@ -45,7 +43,7 @@
/** Generic signature information if the attribute is present in the input */
private FieldTypeSignature genericSignature;
- private FieldOptimizationInfo optimizationInfo;
+ private FieldOptimizationInfo optimizationInfo = DefaultFieldOptimizationInfo.getInstance();
private KotlinFieldLevelInfo kotlinMemberInfo = getNoKotlinInfo();
private static void specify(StructuralSpecification<DexEncodedField, ?> spec) {
@@ -98,20 +96,11 @@
boolean deprecated,
boolean d8R8Synthesized,
AndroidApiLevel apiLevel) {
- super(field, annotations, d8R8Synthesized);
+ super(field, annotations, d8R8Synthesized, apiLevel);
this.accessFlags = accessFlags;
this.staticValue = staticValue;
this.deprecated = deprecated;
this.genericSignature = genericSignature;
- if (apiLevel == AndroidApiLevel.UNKNOWN) {
- optimizationInfo = DefaultFieldOptimizationInfo.getInstance();
- } else if (apiLevel == MIN_API_LEVEL) {
- optimizationInfo = DefaultFieldOptimizationWithMinApiInfo.getInstance();
- } else {
- MutableFieldOptimizationInfo optimizationInfo = new MutableFieldOptimizationInfo();
- this.optimizationInfo = optimizationInfo;
- optimizationInfo.setApiReferenceLevelForDefinition(apiLevel);
- }
assert genericSignature != null;
assert GenericSignatureUtils.verifyNoDuplicateGenericDefinitions(genericSignature, annotations);
}
@@ -148,8 +137,8 @@
}
@Override
- public AndroidApiLevel getApiReferenceLevel(AndroidApiLevel minApiLevel) {
- return optimizationInfo.getApiReferenceLevelForDefinition(minApiLevel);
+ public AndroidApiLevel getApiLevel() {
+ return getApiLevelForDefinition();
}
public synchronized MutableFieldOptimizationInfo getMutableOptimizationInfo() {
@@ -162,10 +151,6 @@
optimizationInfo = info;
}
- public void setMinApiOptimizationInfo(DefaultFieldOptimizationWithMinApiInfo info) {
- optimizationInfo = info;
- }
-
@Override
public KotlinFieldLevelInfo getKotlinInfo() {
return kotlinMemberInfo;
@@ -400,6 +385,7 @@
private FieldAccessFlags accessFlags;
private FieldTypeSignature genericSignature;
private DexValue staticValue;
+ private AndroidApiLevel apiLevel;
private FieldOptimizationInfo optimizationInfo;
private boolean deprecated;
private boolean d8R8Synthesized;
@@ -413,6 +399,7 @@
genericSignature = from.getGenericSignature();
annotations = from.annotations();
staticValue = from.staticValue;
+ apiLevel = from.getApiLevel();
optimizationInfo =
from.optimizationInfo.isMutableOptimizationInfo()
? from.optimizationInfo.asMutableFieldOptimizationInfo().mutableCopy()
@@ -468,7 +455,7 @@
staticValue,
deprecated,
d8R8Synthesized,
- AndroidApiLevel.UNKNOWN);
+ apiLevel);
dexEncodedField.optimizationInfo = optimizationInfo;
buildConsumer.accept(dexEncodedField);
return dexEncodedField;
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
index c1ce2f5..da3c5ff 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
@@ -20,12 +20,20 @@
// set.
private final boolean d8R8Synthesized;
+ /** apiLevelForDefinition describes the api level needed for knowing all types */
+ private AndroidApiLevel apiLevelForDefinition;
+
private final R reference;
- public DexEncodedMember(R reference, DexAnnotationSet annotations, boolean d8R8Synthesized) {
+ public DexEncodedMember(
+ R reference,
+ DexAnnotationSet annotations,
+ boolean d8R8Synthesized,
+ AndroidApiLevel apiLevelForDefinition) {
super(annotations);
this.reference = reference;
this.d8R8Synthesized = d8R8Synthesized;
+ this.apiLevelForDefinition = apiLevelForDefinition;
}
public abstract KotlinMemberLevelInfo getKotlinInfo();
@@ -85,7 +93,15 @@
public abstract MemberOptimizationInfo<?> getOptimizationInfo();
- public abstract AndroidApiLevel getApiReferenceLevel(AndroidApiLevel minApiLevel);
+ public abstract AndroidApiLevel getApiLevel();
+
+ public AndroidApiLevel getApiLevelForDefinition() {
+ return apiLevelForDefinition;
+ }
+
+ public void setApiLevelForDefinition(AndroidApiLevel apiLevelForDefinition) {
+ this.apiLevelForDefinition = apiLevelForDefinition;
+ }
@Override
public final boolean equals(Object other) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index cb44ff9..7b8e309 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -11,7 +11,6 @@
import static com.android.tools.r8.graph.DexEncodedMethod.CompilationState.PROCESSED_NOT_INLINING_CANDIDATE;
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.getNoKotlinInfo;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.MIN_API_LEVEL;
import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
import com.android.tools.r8.cf.CfVersion;
@@ -57,7 +56,6 @@
import com.android.tools.r8.ir.optimize.NestUtils;
import com.android.tools.r8.ir.optimize.info.CallSiteOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.DefaultMethodOptimizationInfo;
-import com.android.tools.r8.ir.optimize.info.DefaultMethodOptimizationWithMinApiInfo;
import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.MutableMethodOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
@@ -158,9 +156,12 @@
// TODO(b/128967328): towards finer-grained inlining constraints,
// we need to maintain a set of states with (potentially different) contexts.
private CompilationState compilationState = CompilationState.NOT_PROCESSED;
- private MethodOptimizationInfo optimizationInfo = DefaultMethodOptimizationInfo.DEFAULT_INSTANCE;
+ private MethodOptimizationInfo optimizationInfo = DefaultMethodOptimizationInfo.getInstance();
private CallSiteOptimizationInfo callSiteOptimizationInfo = CallSiteOptimizationInfo.bottom();
private CfVersion classFileVersion;
+ /** The apiLevelForCode describes the api level needed for knowing all references in the code */
+ private AndroidApiLevel apiLevelForCode;
+
private KotlinMethodLevelInfo kotlinMemberInfo = getNoKotlinInfo();
/** Generic signature information if the attribute is present in the input */
private MethodTypeSignature genericSignature;
@@ -316,28 +317,18 @@
AndroidApiLevel apiLevelForDefinition,
AndroidApiLevel apiLevelForCode,
boolean deprecated) {
- super(method, annotations, d8R8Synthesized);
+ super(method, annotations, d8R8Synthesized, apiLevelForDefinition);
this.accessFlags = accessFlags;
this.deprecated = deprecated;
this.genericSignature = genericSignature;
this.parameterAnnotationsList = parameterAnnotationsList;
this.code = code;
this.classFileVersion = classFileVersion;
- if (apiLevelForDefinition == AndroidApiLevel.UNKNOWN
- && apiLevelForCode == AndroidApiLevel.UNKNOWN) {
- optimizationInfo = DefaultMethodOptimizationInfo.getInstance();
- } else if (apiLevelForDefinition == MIN_API_LEVEL && apiLevelForCode == MIN_API_LEVEL) {
- optimizationInfo = DefaultMethodOptimizationWithMinApiInfo.getInstance();
- } else {
- MutableMethodOptimizationInfo optimizationInfo =
- DefaultMethodOptimizationInfo.getInstance().toMutableOptimizationInfo();
- optimizationInfo.setApiReferenceLevelForDefinition(apiLevelForDefinition);
- optimizationInfo.setApiReferenceLevelForCode(apiLevelForCode);
- this.optimizationInfo = optimizationInfo;
- }
+ this.apiLevelForCode = apiLevelForCode;
assert accessFlags != null;
assert code == null || !shouldNotHaveCode();
assert parameterAnnotationsList != null;
+ assert apiLevelForCode != null && apiLevelForDefinition != null;
}
public static DexEncodedMethod toMethodDefinitionOrNull(DexClassAndMethod method) {
@@ -1431,18 +1422,19 @@
return optimizationInfo;
}
- public AndroidApiLevel getApiReferenceLevelForDefinition(AndroidApiLevel minApiLevel) {
- return optimizationInfo.getApiReferenceLevelForDefinition(minApiLevel);
+ public AndroidApiLevel getApiLevelForCode() {
+ return apiLevelForCode;
}
- public AndroidApiLevel getApiReferenceLevelForCode(AndroidApiLevel minApiLevel) {
- return optimizationInfo.getApiReferenceLevelForCode(minApiLevel);
+ public void setApiLevelForCode(AndroidApiLevel apiLevel) {
+ assert apiLevel != null;
+ this.apiLevelForCode = apiLevel;
}
@Override
- public AndroidApiLevel getApiReferenceLevel(AndroidApiLevel minApiLevel) {
- return getApiReferenceLevelForDefinition(minApiLevel)
- .max(getApiReferenceLevelForCode(minApiLevel));
+ public AndroidApiLevel getApiLevel() {
+ return (isAbstract() ? AndroidApiLevel.B : getApiLevelForCode())
+ .max(getApiLevelForDefinition());
}
public synchronized MutableMethodOptimizationInfo getMutableOptimizationInfo() {
@@ -1457,11 +1449,6 @@
optimizationInfo = info;
}
- public void setMinApiOptimizationInfo(DefaultMethodOptimizationWithMinApiInfo info) {
- checkIfObsolete();
- optimizationInfo = info;
- }
-
public synchronized void abandonCallSiteOptimizationInfo() {
checkIfObsolete();
callSiteOptimizationInfo = CallSiteOptimizationInfo.abandoned();
@@ -1525,6 +1512,8 @@
private MethodOptimizationInfo optimizationInfo = DefaultMethodOptimizationInfo.getInstance();
private KotlinMethodLevelInfo kotlinInfo = getNoKotlinInfo();
private CfVersion classFileVersion = null;
+ private AndroidApiLevel apiLevelForDefinition = null;
+ private AndroidApiLevel apiLevelForCode = null;
private boolean d8R8Synthesized = false;
private Consumer<DexEncodedMethod> buildConsumer = ConsumerUtils.emptyConsumer();
@@ -1542,6 +1531,8 @@
genericSignature = from.getGenericSignature();
annotations = from.annotations();
code = from.getCode();
+ apiLevelForDefinition = from.getApiLevelForDefinition();
+ apiLevelForCode = from.getApiLevelForCode();
optimizationInfo =
from.getOptimizationInfo().isMutableOptimizationInfo()
? from.getOptimizationInfo().asMutableMethodOptimizationInfo().mutableCopy()
@@ -1732,6 +1723,8 @@
assert parameterAnnotations != null;
assert parameterAnnotations.isEmpty()
|| parameterAnnotations.size() == method.proto.parameters.size();
+ assert apiLevelForDefinition != null;
+ assert apiLevelForCode != null;
DexEncodedMethod result =
new DexEncodedMethod(
method,
@@ -1742,8 +1735,8 @@
code,
d8R8Synthesized,
classFileVersion,
- AndroidApiLevel.UNKNOWN,
- AndroidApiLevel.UNKNOWN);
+ apiLevelForDefinition,
+ apiLevelForCode);
result.setKotlinMemberInfo(kotlinInfo);
result.compilationState = compilationState;
result.optimizationInfo = optimizationInfo;
@@ -1758,5 +1751,15 @@
this.genericSignature = methodSignature;
return this;
}
+
+ public Builder setApiLevelForDefinition(AndroidApiLevel apiLevelForDefinition) {
+ this.apiLevelForDefinition = apiLevelForDefinition;
+ return this;
+ }
+
+ public Builder setApiLevelForCode(AndroidApiLevel apiLevelForCode) {
+ this.apiLevelForCode = apiLevelForCode;
+ return this;
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 8a3f39a..e297bd4 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.graph;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.getNoKotlinInfo;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabled;
+import static com.android.tools.r8.utils.AndroidApiLevel.minApiLevelIfEnabledOrUnknown;
import static com.google.common.base.Predicates.alwaysTrue;
import com.android.tools.r8.ProgramResource;
@@ -827,7 +827,7 @@
AppView<?> appView,
BiFunction<DexReference, AndroidApiLevel, AndroidApiLevel> apiLevelLookup) {
// The api level of a class is the max level of it's members, super class and interfaces.
- AndroidApiLevel computedApiLevel = getApiLevelIfEnabled(appView, Function.identity());
+ AndroidApiLevel computedApiLevel = minApiLevelIfEnabledOrUnknown(appView);
for (DexType superType : allImmediateSupertypes()) {
computedApiLevel = apiLevelLookup.apply(superType, computedApiLevel);
if (computedApiLevel == AndroidApiLevel.UNKNOWN) {
@@ -838,9 +838,9 @@
}
public AndroidApiLevel getMembersApiReferenceLevel(AppView<?> appView) {
- AndroidApiLevel memberLevel = getApiLevelIfEnabled(appView, Function.identity());
+ AndroidApiLevel memberLevel = minApiLevelIfEnabledOrUnknown(appView);
for (DexEncodedMember<?, ?> member : members()) {
- memberLevel = memberLevel.max(getApiLevelIfEnabled(appView, member::getApiReferenceLevel));
+ memberLevel = memberLevel.max(member.getApiLevel());
if (memberLevel == AndroidApiLevel.UNKNOWN) {
return AndroidApiLevel.UNKNOWN;
}
diff --git a/src/main/java/com/android/tools/r8/graph/analysis/ApiModelAnalysis.java b/src/main/java/com/android/tools/r8/graph/analysis/ApiModelAnalysis.java
index b4615df..9da5368 100644
--- a/src/main/java/com/android/tools/r8/graph/analysis/ApiModelAnalysis.java
+++ b/src/main/java/com/android/tools/r8/graph/analysis/ApiModelAnalysis.java
@@ -6,18 +6,11 @@
import com.android.tools.r8.androidapi.AndroidApiReferenceLevelCache;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMember;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexMember;
+import com.android.tools.r8.graph.DexClassAndMember;
import com.android.tools.r8.graph.LookupTarget;
import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.optimize.info.DefaultFieldOptimizationWithMinApiInfo;
-import com.android.tools.r8.ir.optimize.info.DefaultMethodOptimizationInfo;
-import com.android.tools.r8.ir.optimize.info.DefaultMethodOptimizationWithMinApiInfo;
-import com.android.tools.r8.ir.optimize.info.MemberOptimizationInfo;
-import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
import com.android.tools.r8.shaking.DefaultEnqueuerUseRegistry;
import com.android.tools.r8.utils.AndroidApiLevel;
@@ -35,14 +28,12 @@
@Override
public void processNewlyLiveField(ProgramField field, ProgramDefinition context) {
- setApiLevelForMemberDefinition(
- field.getDefinition(), computeApiLevelForReferencedTypes(field.getReference()));
+ computeApiLevelForDefinition(field);
}
@Override
public void processNewlyLiveMethod(ProgramMethod method, ProgramDefinition context) {
- setApiLevelForMemberDefinition(
- method.getDefinition(), computeApiLevelForReferencedTypes(method.getReference()));
+ computeApiLevelForDefinition(method);
}
@Override
@@ -55,71 +46,35 @@
.tracedMethodApiLevelCallback
.accept(method.getMethodReference(), registry.getMaxApiReferenceLevel());
}
- setApiLevelForMemberDefinition(
- method.getDefinition(), computeApiLevelForReferencedTypes(method.getReference()));
- setApiLevelForCode(method.getDefinition(), registry.getMaxApiReferenceLevel());
+ computeApiLevelForDefinition(method);
+ method.getDefinition().setApiLevelForCode(registry.getMaxApiReferenceLevel());
}
@Override
public void notifyMarkMethodAsTargeted(ProgramMethod method) {
- setApiLevelForMemberDefinition(method.getDefinition(), minApiLevel);
+ computeApiLevelForDefinition(method);
}
@Override
public void notifyMarkFieldAsReachable(ProgramField field) {
- setApiLevelForMemberDefinition(field.getDefinition(), minApiLevel);
+ computeApiLevelForDefinition(field);
}
@Override
public void notifyMarkVirtualDispatchTargetAsLive(LookupTarget target) {
target.accept(
- dexClassAndMethod -> {
- setApiLevelForMemberDefinition(dexClassAndMethod.getDefinition(), minApiLevel);
- },
+ this::computeApiLevelForDefinition,
lookupLambdaTarget -> {
// The implementation method will be assigned an api level when visited.
});
}
- private void setApiLevelForMemberDefinition(
- DexEncodedMember<?, ?> member, AndroidApiLevel apiLevel) {
- // To not have mutable update information for all members that all has min api level we
- // swap the default optimization info for one with that marks the api level to be min api.
- MemberOptimizationInfo<?> optimizationInfo = member.getOptimizationInfo();
- if (!optimizationInfo.isMutableOptimizationInfo() && apiLevel == minApiLevel) {
- member.accept(
- field -> {
- field.setMinApiOptimizationInfo(DefaultFieldOptimizationWithMinApiInfo.getInstance());
- },
- method -> {
- method.setMinApiOptimizationInfo(DefaultMethodOptimizationWithMinApiInfo.getInstance());
- });
- } else {
- AndroidApiLevel maxApiLevel =
- optimizationInfo.hasApiReferenceLevelForDefinition()
- ? apiLevel.max(optimizationInfo.getApiReferenceLevelForDefinition(minApiLevel))
- : apiLevel;
- member.accept(
- field -> {
- field.getMutableOptimizationInfo().setApiReferenceLevelForDefinition(maxApiLevel);
- },
- method -> {
- method.getMutableOptimizationInfo().setApiReferenceLevelForDefinition(maxApiLevel);
- });
- }
- }
-
- private void setApiLevelForCode(DexEncodedMethod method, AndroidApiLevel apiLevel) {
- MethodOptimizationInfo optimizationInfo = method.getOptimizationInfo();
- assert optimizationInfo != DefaultMethodOptimizationInfo.getInstance();
- if (!optimizationInfo.isMutableOptimizationInfo() && apiLevel == minApiLevel) {
- assert optimizationInfo == DefaultMethodOptimizationWithMinApiInfo.getInstance();
- return;
- }
- method.getMutableOptimizationInfo().setApiReferenceLevelForCode(apiLevel);
- }
-
- private AndroidApiLevel computeApiLevelForReferencedTypes(DexMember<?, ?> member) {
- return member.computeApiLevelForReferencedTypes(appView, referenceLevelCache::lookupMax);
+ private void computeApiLevelForDefinition(DexClassAndMember<?, ?> member) {
+ member
+ .getDefinition()
+ .setApiLevelForDefinition(
+ member
+ .getReference()
+ .computeApiLevelForReferencedTypes(appView, referenceLevelCache::lookupMax));
}
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
index a772278..43a2c8a 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.horizontalclassmerging;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabledForNewMember;
+import static com.android.tools.r8.utils.AndroidApiLevel.minApiLevelIfEnabledOrUnknown;
import static com.google.common.base.Predicates.not;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -45,7 +45,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.function.Function;
/**
* The class merger is responsible for moving methods from the sources in {@link ClassMerger#group}
@@ -141,8 +140,8 @@
classInitializerMerger.getCode(syntheticMethodReference),
DexEncodedMethod.D8_R8_SYNTHESIZED,
classInitializerMerger.getCfVersion(),
- getApiLevelIfEnabledForNewMember(appView, ignored -> apiReferenceLevel),
- getApiLevelIfEnabledForNewMember(appView, ignored -> apiReferenceLevel));
+ apiReferenceLevel,
+ apiReferenceLevel);
classMethodsBuilder.addDirectMethod(definition);
// In case we didn't synthesize CF code, we register the class initializer for conversion to dex
@@ -230,7 +229,7 @@
null,
deprecated,
d8R8Synthesized,
- getApiLevelIfEnabledForNewMember(appView, Function.identity()));
+ minApiLevelIfEnabledOrUnknown(appView));
// For the $r8$classId synthesized fields, we try to over-approximate the set of values it may
// have. For example, for a merge group of size 4, we may compute the set {0, 2, 3}, if the
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
index adc89fc..d6ae971 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.horizontalclassmerging;
import static com.android.tools.r8.dex.Constants.TEMPORARY_INSTANCE_INITIALIZER_PREFIX;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabledForNewMember;
import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.dex.Constants;
@@ -372,10 +371,8 @@
getNewCode(newMethodReference, syntheticMethodReference, needsClassId, extraNulls),
true,
getNewClassFileVersion(),
- getApiLevelIfEnabledForNewMember(
- appView, representativeMethod::getApiReferenceLevelForDefinition),
- getApiLevelIfEnabledForNewMember(
- appView, representativeMethod::getApiReferenceLevelForCode));
+ representativeMethod.getApiLevelForDefinition(),
+ representativeMethod.getApiLevelForCode());
classMethodsBuilder.addDirectMethod(newInstanceInitializer);
if (mode.isFinal()) {
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
index 87a3211..be6a5a2 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.horizontalclassmerging;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabledForNewMember;
-
import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
@@ -289,10 +287,8 @@
synthesizedCode,
true,
classFileVersion,
- getApiLevelIfEnabledForNewMember(
- appView, representativeMethod::getApiReferenceLevelForDefinition),
- getApiLevelIfEnabledForNewMember(
- appView, representativeMethod::getApiReferenceLevelForCode));
+ representativeMethod.getApiLevelForDefinition(),
+ representativeMethod.getApiLevelForCode());
if (!representative.getDefinition().isLibraryMethodOverride().isUnknown()) {
newMethod.setLibraryMethodOverride(representative.getDefinition().isLibraryMethodOverride());
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
index cff4480..3251db1 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.horizontalclassmerging.code;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabled;
+import static com.android.tools.r8.utils.AndroidApiLevel.minApiLevelIfEnabledOrUnknown;
import static java.lang.Integer.max;
import com.android.tools.r8.cf.CfVersion;
@@ -104,12 +104,8 @@
assert !classInitializers.isEmpty();
return ListUtils.fold(
classInitializers,
- appView.options().apiModelingOptions().enableApiCallerIdentification
- ? appView.options().minApiLevel
- : AndroidApiLevel.UNKNOWN,
- (accApiLevel, method) ->
- accApiLevel.max(
- getApiLevelIfEnabled(appView, method.getDefinition()::getApiReferenceLevel)));
+ minApiLevelIfEnabledOrUnknown(appView),
+ (accApiLevel, method) -> accApiLevel.max(method.getDefinition().getApiLevel()));
}
public static class Builder {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 88f451b..61e6828 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.ir.desugar;
import static com.android.tools.r8.ir.desugar.lambda.ForcefullyMovedLambdaMethodConsumer.emptyForcefullyMovedLambdaMethodConsumer;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabledForNewMember;
import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
import com.android.tools.r8.dex.Constants;
@@ -40,11 +39,11 @@
import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.synthesis.SyntheticProgramClassBuilder;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
-import java.util.function.Function;
/**
* Represents lambda class generated for a lambda descriptor in context of lambda instantiation
@@ -109,7 +108,7 @@
this.lambdaField =
!stateless ? null : factory.createField(type, type, factory.lambdaInstanceFieldName);
- // Synthesize the program class one all fields are set.
+ // Synthesize the program class once all fields are set.
synthesizeLambdaClass(builder);
}
@@ -244,7 +243,8 @@
null,
deprecated,
d8R8Synthesized,
- getApiLevelIfEnabledForNewMember(appView, Function.identity())));
+ // The api level is computed when tracing.
+ AndroidApiLevel.minApiLevelIfEnabledOrUnknown(appView)));
}
builder.setInstanceFields(fields);
}
@@ -270,7 +270,8 @@
DexValueNull.NULL,
deprecated,
d8R8Synthesized,
- getApiLevelIfEnabledForNewMember(appView, Function.identity()))));
+ // The api level is computed when tracing.
+ AndroidApiLevel.minApiLevelIfEnabledOrUnknown(appView))));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/AccessBridgeFactory.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/AccessBridgeFactory.java
index 9266ad9..8814c2e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/nest/AccessBridgeFactory.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/AccessBridgeFactory.java
@@ -38,6 +38,8 @@
.build())
.setMethod(bridgeMethodReference)
.setD8R8Synthesized()
+ .setApiLevelForDefinition(field.getDefinition().getApiLevel())
+ .setApiLevelForCode(field.getDefinition().getApiLevel())
.build());
}
@@ -59,6 +61,8 @@
.build())
.setMethod(bridgeMethodReference)
.setD8R8Synthesized()
+ .setApiLevelForDefinition(method.getDefinition().getApiLevelForDefinition())
+ .setApiLevelForCode(method.getDefinition().getApiLevelForCode())
.build());
}
@@ -87,6 +91,8 @@
builder -> builder.setDirectTarget(method.getReference(), isInterface))
.build())
.setMethod(bridgeMethodReference)
+ .setApiLevelForDefinition(method.getDefinition().getApiLevelForDefinition())
+ .setApiLevelForCode(method.getDefinition().getApiLevelForDefinition())
.setD8R8Synthesized()
.build());
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/SharedEnumUnboxingUtilityClass.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/SharedEnumUnboxingUtilityClass.java
index 7a95765..9614ede 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/SharedEnumUnboxingUtilityClass.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/SharedEnumUnboxingUtilityClass.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.ir.optimize.enums;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabledForNewMember;
+import static com.android.tools.r8.utils.AndroidApiLevel.minApiLevelIfEnabledOrUnknown;
import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.cf.code.CfArrayStore;
@@ -48,7 +48,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
-import java.util.function.Function;
import org.objectweb.asm.Opcodes;
public class SharedEnumUnboxingUtilityClass extends EnumUnboxingUtilityClass {
@@ -238,7 +237,7 @@
DexEncodedField.NO_STATIC_VALUE,
DexEncodedField.NOT_DEPRECATED,
DexEncodedField.D8_R8_SYNTHESIZED,
- getApiLevelIfEnabledForNewMember(appView, Function.identity()));
+ minApiLevelIfEnabledOrUnknown(appView));
fieldAccessInfoCollectionModifierBuilder
.recordFieldReadInUnknownContext(valuesField.getReference())
.recordFieldWriteInUnknownContext(valuesField.getReference());
@@ -258,8 +257,8 @@
createClassInitializerCode(sharedUtilityClassType, valuesField),
DexEncodedMethod.D8_R8_SYNTHESIZED,
CfVersion.V1_6,
- getApiLevelIfEnabledForNewMember(appView, Function.identity()),
- getApiLevelIfEnabledForNewMember(appView, Function.identity()));
+ minApiLevelIfEnabledOrUnknown(appView),
+ minApiLevelIfEnabledOrUnknown(appView));
}
private CfCode createClassInitializerCode(
@@ -305,8 +304,8 @@
createValuesMethodCode(sharedUtilityClassType, valuesField),
DexEncodedMethod.D8_R8_SYNTHESIZED,
CfVersion.V1_6,
- getApiLevelIfEnabledForNewMember(appView, Function.identity()),
- getApiLevelIfEnabledForNewMember(appView, Function.identity()));
+ minApiLevelIfEnabledOrUnknown(appView),
+ minApiLevelIfEnabledOrUnknown(appView));
this.valuesMethod = valuesMethod;
return valuesMethod;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultFieldOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultFieldOptimizationInfo.java
index 4fd2fcd..c790a02 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultFieldOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultFieldOptimizationInfo.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.UnknownValue;
-import com.android.tools.r8.utils.AndroidApiLevel;
public class DefaultFieldOptimizationInfo extends FieldOptimizationInfo {
@@ -56,11 +55,6 @@
}
@Override
- public AndroidApiLevel getApiReferenceLevelForDefinition(AndroidApiLevel minApi) {
- throw new RuntimeException("Should never be called");
- }
-
- @Override
public MutableFieldOptimizationInfo toMutableOptimizationInfo() {
return new MutableFieldOptimizationInfo();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultFieldOptimizationWithMinApiInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultFieldOptimizationWithMinApiInfo.java
deleted file mode 100644
index a9c7462..0000000
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultFieldOptimizationWithMinApiInfo.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.ir.optimize.info;
-
-import com.android.tools.r8.utils.AndroidApiLevel;
-
-public class DefaultFieldOptimizationWithMinApiInfo extends DefaultFieldOptimizationInfo {
-
- private static final DefaultFieldOptimizationWithMinApiInfo INSTANCE =
- new DefaultFieldOptimizationWithMinApiInfo();
-
- public static DefaultFieldOptimizationWithMinApiInfo getInstance() {
- return INSTANCE;
- }
-
- @Override
- public boolean hasApiReferenceLevelForDefinition() {
- return true;
- }
-
- @Override
- public AndroidApiLevel getApiReferenceLevelForDefinition(AndroidApiLevel minApi) {
- return minApi;
- }
-
- @Override
- public MutableFieldOptimizationInfo toMutableOptimizationInfo() {
- MutableFieldOptimizationInfo updatableFieldOptimizationInfo = super.toMutableOptimizationInfo();
- // Use null to specify that the min api is set to minApi.
- updatableFieldOptimizationInfo.setMinApiReferenceLevel();
- return updatableFieldOptimizationInfo;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
index 31ecb9b..24aeb3d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
@@ -18,7 +18,6 @@
import com.android.tools.r8.ir.optimize.info.bridge.BridgeInfo;
import com.android.tools.r8.ir.optimize.info.initializer.DefaultInstanceInitializerInfo;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
-import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableSet;
import java.util.BitSet;
@@ -196,26 +195,6 @@
}
@Override
- public boolean hasApiReferenceLevelForCode() {
- return false;
- }
-
- @Override
- public AndroidApiLevel getApiReferenceLevelForCode(AndroidApiLevel minApi) {
- throw new RuntimeException("Should never be called");
- }
-
- @Override
- public AndroidApiLevel getApiReferenceLevelForDefinition(AndroidApiLevel minApi) {
- throw new RuntimeException("Should never be called");
- }
-
- @Override
- public boolean hasApiReferenceLevelForDefinition() {
- return false;
- }
-
- @Override
public MutableMethodOptimizationInfo toMutableOptimizationInfo() {
return new MutableMethodOptimizationInfo();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationWithMinApiInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationWithMinApiInfo.java
deleted file mode 100644
index cd06dee..0000000
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationWithMinApiInfo.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.ir.optimize.info;
-
-import com.android.tools.r8.utils.AndroidApiLevel;
-
-public class DefaultMethodOptimizationWithMinApiInfo extends DefaultMethodOptimizationInfo {
-
- private static final DefaultMethodOptimizationWithMinApiInfo DEFAULT_MIN_API_INSTANCE =
- new DefaultMethodOptimizationWithMinApiInfo();
-
- public static DefaultMethodOptimizationWithMinApiInfo getInstance() {
- return DEFAULT_MIN_API_INSTANCE;
- }
-
- @Override
- public boolean hasApiReferenceLevelForDefinition() {
- return true;
- }
-
- @Override
- public AndroidApiLevel getApiReferenceLevelForDefinition(AndroidApiLevel minApi) {
- return minApi;
- }
-
- @Override
- public boolean hasApiReferenceLevelForCode() {
- return true;
- }
-
- @Override
- public AndroidApiLevel getApiReferenceLevelForCode(AndroidApiLevel minApi) {
- return minApi;
- }
-
- @Override
- public MutableMethodOptimizationInfo toMutableOptimizationInfo() {
- MutableMethodOptimizationInfo updatableMethodOptimizationInfo =
- super.toMutableOptimizationInfo();
- // Use null to specify that the min api is set to minApi.
- updatableMethodOptimizationInfo.setMinApiReferenceLevel();
- return updatableMethodOptimizationInfo;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MemberOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MemberOptimizationInfo.java
index 9cb8a2a..f5242e9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MemberOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MemberOptimizationInfo.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.ir.optimize.info;
-import com.android.tools.r8.utils.AndroidApiLevel;
-
public interface MemberOptimizationInfo<
T extends MemberOptimizationInfo<T> & MutableOptimizationInfo> {
@@ -21,12 +19,6 @@
return null;
}
- default boolean hasApiReferenceLevelForDefinition() {
- return false;
- }
-
- AndroidApiLevel getApiReferenceLevelForDefinition(AndroidApiLevel minApi);
-
T toMutableOptimizationInfo();
default boolean isFieldOptimizationInfo() {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
index bb45fbc..aab9aa6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
@@ -15,7 +15,6 @@
import com.android.tools.r8.ir.optimize.enums.classification.EnumUnboxerMethodClassification;
import com.android.tools.r8.ir.optimize.info.bridge.BridgeInfo;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
-import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import java.util.BitSet;
import java.util.Set;
@@ -101,10 +100,6 @@
public abstract boolean returnValueHasBeenPropagated();
- public abstract boolean hasApiReferenceLevelForCode();
-
- public abstract AndroidApiLevel getApiReferenceLevelForCode(AndroidApiLevel minApi);
-
@Override
public boolean isMethodOptimizationInfo() {
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
index bdab6e8..9150ea0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
@@ -15,8 +15,6 @@
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.UnknownValue;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.util.Optional;
import java.util.Set;
/**
@@ -38,7 +36,6 @@
private int readBits = 0;
private ClassTypeElement dynamicLowerBoundType = null;
private TypeElement dynamicUpperBoundType = null;
- private Optional<AndroidApiLevel> apiReferenceLevel = null;
public MutableFieldOptimizationInfo fixupClassTypeReferences(
AppView<? extends AppInfoWithClassHierarchy> appView, GraphLens lens) {
@@ -69,7 +66,6 @@
public MutableFieldOptimizationInfo mutableCopy() {
MutableFieldOptimizationInfo copy = new MutableFieldOptimizationInfo();
copy.flags = flags;
- copy.apiReferenceLevel = apiReferenceLevel;
return copy;
}
@@ -154,29 +150,4 @@
public MutableFieldOptimizationInfo asMutableFieldOptimizationInfo() {
return this;
}
-
- @SuppressWarnings("OptionalAssignedToNull")
- @Override
- public boolean hasApiReferenceLevelForDefinition() {
- return apiReferenceLevel != null;
- }
-
- @Override
- public AndroidApiLevel getApiReferenceLevelForDefinition(AndroidApiLevel minApi) {
- assert hasApiReferenceLevelForDefinition();
- return apiReferenceLevel.orElse(minApi);
- }
-
- @Override
- @SuppressWarnings("OptionalAssignedToNull")
- public void setMinApiReferenceLevel() {
- assert apiReferenceLevel == null;
- this.apiReferenceLevel = Optional.empty();
- }
-
- @Override
- public void setApiReferenceLevelForDefinition(AndroidApiLevel apiReferenceLevel) {
- assert apiReferenceLevel != null;
- this.apiReferenceLevel = Optional.of(apiReferenceLevel);
- }
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
index 54184d78..3efe7f6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
@@ -25,11 +25,9 @@
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.InternalOptions;
import java.util.BitSet;
-import java.util.Optional;
import java.util.Set;
public class MutableMethodOptimizationInfo extends MethodOptimizationInfo
@@ -75,9 +73,6 @@
private SimpleInliningConstraint simpleInliningConstraint =
NeverSimpleInliningConstraint.getInstance();
- private Optional<AndroidApiLevel> codeApiReferenceLevel = null;
- private Optional<AndroidApiLevel> definitionApiReferenceLevel = null;
-
// To reduce the memory footprint of UpdatableMethodOptimizationInfo, all the boolean fields are
// merged into a flag int field. The various static final FLAG fields indicate which bit is
// used by each boolean. DEFAULT_FLAGS encodes the default value for efficient instantiation and
@@ -159,8 +154,6 @@
nonNullParamOnNormalExits = template.nonNullParamOnNormalExits;
classInlinerConstraint = template.classInlinerConstraint;
enumUnboxerMethodClassification = template.enumUnboxerMethodClassification;
- definitionApiReferenceLevel = template.definitionApiReferenceLevel;
- codeApiReferenceLevel = template.codeApiReferenceLevel;
}
public MutableMethodOptimizationInfo fixupClassTypeReferences(
@@ -536,50 +529,6 @@
}
@Override
- public AndroidApiLevel getApiReferenceLevelForDefinition(AndroidApiLevel minApi) {
- assert hasApiReferenceLevelForDefinition();
- return definitionApiReferenceLevel.orElse(minApi);
- }
-
- @SuppressWarnings("OptionalAssignedToNull")
- @Override
- public boolean hasApiReferenceLevelForDefinition() {
- return definitionApiReferenceLevel != null;
- }
-
- @Override
- @SuppressWarnings("OptionalAssignedToNull")
- public boolean hasApiReferenceLevelForCode() {
- return codeApiReferenceLevel != null;
- }
-
- @Override
- public AndroidApiLevel getApiReferenceLevelForCode(AndroidApiLevel minApi) {
- assert hasApiReferenceLevelForCode();
- return codeApiReferenceLevel.orElse(minApi);
- }
-
- @Override
- @SuppressWarnings("OptionalAssignedToNull")
- public void setMinApiReferenceLevel() {
- assert codeApiReferenceLevel == null;
- assert definitionApiReferenceLevel == null;
- this.codeApiReferenceLevel = Optional.empty();
- this.definitionApiReferenceLevel = Optional.empty();
- }
-
- public void setApiReferenceLevelForCode(AndroidApiLevel apiLevel) {
- assert apiLevel != null;
- this.codeApiReferenceLevel = Optional.of(apiLevel);
- }
-
- @Override
- public void setApiReferenceLevelForDefinition(AndroidApiLevel apiLevel) {
- assert apiLevel != null;
- this.definitionApiReferenceLevel = Optional.of(apiLevel);
- }
-
- @Override
public boolean isMutableOptimizationInfo() {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableOptimizationInfo.java
index 421f689..58f5470 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableOptimizationInfo.java
@@ -4,11 +4,6 @@
package com.android.tools.r8.ir.optimize.info;
-import com.android.tools.r8.utils.AndroidApiLevel;
-
public interface MutableOptimizationInfo {
- void setMinApiReferenceLevel();
-
- void setApiReferenceLevelForDefinition(AndroidApiLevel apiLevel);
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ClassInitFieldSynthesizer.java b/src/main/java/com/android/tools/r8/shaking/ClassInitFieldSynthesizer.java
index 3d76d73..bfc3ae7 100644
--- a/src/main/java/com/android/tools/r8/shaking/ClassInitFieldSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/shaking/ClassInitFieldSynthesizer.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.shaking;
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabledForNewMember;
+import static com.android.tools.r8.utils.AndroidApiLevel.minApiLevelIfEnabledOrUnknown;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
@@ -22,7 +22,6 @@
import com.android.tools.r8.utils.Visibility;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-import java.util.function.Function;
public class ClassInitFieldSynthesizer {
@@ -93,7 +92,7 @@
null,
deprecated,
DexEncodedField.D8_R8_SYNTHESIZED,
- getApiLevelIfEnabledForNewMember(appView, Function.identity()));
+ minApiLevelIfEnabledOrUnknown(appView));
clazz.appendStaticField(encodedClinitField);
}
lensBuilder.map(type, encodedClinitField.getReference());
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 0a49379..27d25bb 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -7,7 +7,6 @@
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import static com.android.tools.r8.ir.code.Invoke.Type.DIRECT;
import static com.android.tools.r8.ir.code.Invoke.Type.STATIC;
-import static com.android.tools.r8.utils.AndroidApiLevelUtils.getApiLevelIfEnabledForNewMember;
import com.android.tools.r8.androidapi.AndroidApiReferenceLevelCache;
import com.android.tools.r8.errors.Unreachable;
@@ -1451,8 +1450,8 @@
code,
true,
method.hasClassFileVersion() ? method.getClassFileVersion() : null,
- getApiLevelIfEnabledForNewMember(appView, method::getApiReferenceLevelForDefinition),
- getApiLevelIfEnabledForNewMember(appView, Function.identity()));
+ method.getApiLevelForDefinition(),
+ method.getApiLevelForDefinition());
bridge.setLibraryMethodOverride(method.isLibraryMethodOverride());
if (method.accessFlags.isPromotedToPublic()) {
// The bridge is now the public method serving the role of the original method, and should
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java b/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
index 1e4082b..e127d6c 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.utils;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.utils.structural.Ordered;
import java.util.Arrays;
import java.util.List;
@@ -75,6 +76,12 @@
return DexVersion.getDexVersion(this);
}
+ public static AndroidApiLevel minApiLevelIfEnabledOrUnknown(AppView<?> appView) {
+ return appView.options().apiModelingOptions().enableApiCallerIdentification
+ ? appView.options().minApiLevel
+ : UNKNOWN;
+ }
+
public static List<AndroidApiLevel> getAndroidApiLevelsSorted() {
return Arrays.asList(AndroidApiLevel.values());
}
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
index 9272066..96c4a2b 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
@@ -4,32 +4,10 @@
package com.android.tools.r8.utils;
-import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
-import java.util.function.Function;
public class AndroidApiLevelUtils {
- // Static api-level indicating that the api level is min-api.
- public static final AndroidApiLevel MIN_API_LEVEL = null;
-
- public static AndroidApiLevel getApiLevelIfEnabledForNewMember(
- AppView<?> appView, Function<AndroidApiLevel, AndroidApiLevel> getter) {
- AndroidApiLevel apiLevelIfEnabled = getApiLevelIfEnabled(appView, getter);
- if (apiLevelIfEnabled == appView.options().minApiLevel) {
- return MIN_API_LEVEL;
- }
- return apiLevelIfEnabled;
- }
-
- public static AndroidApiLevel getApiLevelIfEnabled(
- AppView<?> appView, Function<AndroidApiLevel, AndroidApiLevel> getter) {
- if (!appView.options().apiModelingOptions().enableApiCallerIdentification) {
- return AndroidApiLevel.UNKNOWN;
- }
- return getter.apply(appView.options().minApiLevel);
- }
-
public static OptionalBool isApiSafeForInlining(
ProgramMethod caller, ProgramMethod inlinee, InternalOptions options) {
if (!options.apiModelingOptions().enableApiCallerIdentification) {
@@ -41,8 +19,7 @@
return OptionalBool.of(
caller
.getDefinition()
- .getApiReferenceLevel(options.minApiLevel)
- .isGreaterThanOrEqualTo(
- inlinee.getDefinition().getApiReferenceLevelForCode(options.minApiLevel)));
+ .getApiLevel()
+ .isGreaterThanOrEqualTo(inlinee.getDefinition().getApiLevelForCode()));
}
}