Revert "Build apimodel cache on top of computed database builder"
This reverts commit daa47f2e6851a447036dd660fb7cd2f5434e9bd7.
Reason for revert: Problem building
Change-Id: I6a9683355f5b2b4ed0671ce9934ccbebd258fb8d
diff --git a/src/main/java/com/android/tools/r8/androidapi/AndroidApiClass.java b/src/main/java/com/android/tools/r8/androidapi/AndroidApiClass.java
index ee0ffb2..f33f5bd 100644
--- a/src/main/java/com/android/tools/r8/androidapi/AndroidApiClass.java
+++ b/src/main/java/com/android/tools/r8/androidapi/AndroidApiClass.java
@@ -26,8 +26,6 @@
public abstract AndroidApiLevel getApiLevel();
- public abstract int getMemberCount();
-
public abstract TraversalContinuation visitFields(
BiFunction<FieldReference, AndroidApiLevel, TraversalContinuation> visitor);
diff --git a/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java b/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java
deleted file mode 100644
index 124ea3f..0000000
--- a/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java
+++ /dev/null
@@ -1,150 +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.androidapi;
-
-import com.android.tools.r8.apimodel.AndroidApiDatabaseBuilder;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMember;
-import com.android.tools.r8.graph.DexReference;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.Box;
-import com.android.tools.r8.utils.TraversalContinuation;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-public class AndroidApiReferenceLevelCache {
-
- private static final int BUILD_CACHE_TRESHOLD = 20;
-
- private final Map<DexType, AndroidApiClass> apiTypeLookup;
- private final Map<DexReference, AndroidApiLevel> apiMemberLookup = new IdentityHashMap<>();
- private final AppView<?> appView;
-
- private AndroidApiReferenceLevelCache(AppView<?> appView) {
- this.appView = appView;
- this.apiTypeLookup = new IdentityHashMap<>();
- }
-
- private AndroidApiReferenceLevelCache(
- AppView<?> appView, Map<DexType, AndroidApiClass> apiTypeLookup) {
- this.appView = appView;
- this.apiTypeLookup = apiTypeLookup;
- }
-
- public static AndroidApiReferenceLevelCache create(AppView<?> appView) {
- if (!appView.options().apiModelingOptions().enableApiCallerIdentification) {
- // If enableApiCallerIdentification is not enabled then override lookup to always return
- // AndroidApiLevel.B.
- return new AndroidApiReferenceLevelCache(appView) {
- @Override
- public AndroidApiLevel lookup(DexReference reference) {
- return AndroidApiLevel.B;
- }
- };
- }
- // The apiTypeLookup is build lazily except for the mocked api types that we define in tests
- // externally.
- Map<DexType, AndroidApiClass> apiTypeLookup = new IdentityHashMap<>();
- appView
- .options()
- .apiModelingOptions()
- .visitMockedApiReferences(
- (classReference, androidApiClass) ->
- apiTypeLookup.put(
- appView.dexItemFactory().createType(classReference.getDescriptor()),
- androidApiClass));
- return new AndroidApiReferenceLevelCache(appView, apiTypeLookup);
- }
-
- public AndroidApiLevel lookupMax(DexReference reference, AndroidApiLevel minApiLevel) {
- return lookup(reference).max(minApiLevel);
- }
-
- public AndroidApiLevel lookup(DexReference reference) {
- DexType contextType = reference.getContextType();
- assert !contextType.isArrayType();
- if (contextType.isPrimitiveType() || contextType.isVoidType()) {
- return AndroidApiLevel.B;
- }
- DexClass clazz = appView.definitionFor(contextType);
- if (clazz == null) {
- return AndroidApiLevel.UNKNOWN;
- }
- if (!clazz.isLibraryClass()) {
- return appView.options().minApiLevel;
- }
- AndroidApiClass androidApiClass =
- apiTypeLookup.computeIfAbsent(
- contextType, type -> AndroidApiDatabaseBuilder.buildClass(type.asClassReference()));
- if (androidApiClass == null) {
- // This is a library class but we have no api model for it. This happens if using an older
- // version of R8 to compile a new target. We simply have to disallow inlining of methods
- // that has such references.
- return AndroidApiLevel.UNKNOWN;
- }
- if (reference.isDexType()) {
- return androidApiClass.getApiLevel();
- }
- return androidApiClass.getMemberCount() > BUILD_CACHE_TRESHOLD
- ? findMemberByCaching(reference, androidApiClass)
- : findMemberByIteration(reference.asDexMember(), androidApiClass);
- }
-
- private AndroidApiLevel findMemberByIteration(
- DexMember<?, ?> reference, AndroidApiClass apiClass) {
- DexItemFactory factory = appView.dexItemFactory();
- // Similar to the case for api classes we are unable to find, if the member
- // is unknown we have to be conservative.
- Box<AndroidApiLevel> apiLevelBox = new Box<>(AndroidApiLevel.UNKNOWN);
- reference.apply(
- field ->
- apiClass.visitFields(
- (fieldReference, apiLevel) -> {
- if (factory.createField(fieldReference) == field) {
- apiLevelBox.set(apiLevel);
- return TraversalContinuation.BREAK;
- }
- return TraversalContinuation.CONTINUE;
- }),
- method ->
- apiClass.visitMethods(
- (methodReference, apiLevel) -> {
- if (factory.createMethod(methodReference) == method) {
- apiLevelBox.set(apiLevel);
- return TraversalContinuation.BREAK;
- }
- return TraversalContinuation.CONTINUE;
- }));
- return apiLevelBox.get();
- }
-
- private AndroidApiLevel findMemberByCaching(DexReference reference, AndroidApiClass apiClass) {
- buildCacheForMembers(reference.getContextType(), apiClass);
- return apiMemberLookup.getOrDefault(reference, AndroidApiLevel.UNKNOWN);
- }
-
- private void buildCacheForMembers(DexType context, AndroidApiClass apiClass) {
- assert apiClass.getMemberCount() > BUILD_CACHE_TRESHOLD;
- // Use the context type as a token for us having build a cache for it.
- if (apiMemberLookup.containsKey(context)) {
- return;
- }
- DexItemFactory factory = appView.dexItemFactory();
- apiClass.visitFields(
- (fieldReference, apiLevel) -> {
- apiMemberLookup.put(factory.createField(fieldReference), apiLevel);
- return TraversalContinuation.CONTINUE;
- });
- apiClass.visitMethods(
- (methodReference, apiLevel) -> {
- apiMemberLookup.put(factory.createMethod(methodReference), apiLevel);
- return TraversalContinuation.CONTINUE;
- });
- apiMemberLookup.put(context, AndroidApiLevel.UNKNOWN);
- }
-}
diff --git a/src/main/java/com/android/tools/r8/graph/DexMember.java b/src/main/java/com/android/tools/r8/graph/DexMember.java
index bffc842..ae9d9fb 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMember.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMember.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.Iterables;
-import java.util.function.BiFunction;
+import java.util.Map;
import java.util.function.Function;
public abstract class DexMember<D extends DexEncodedMember<D, R>, R extends DexMember<D, R>>
@@ -64,11 +64,12 @@
}
public AndroidApiLevel computeApiLevelForReferencedTypes(
- AppView<?> appView, BiFunction<DexReference, AndroidApiLevel, AndroidApiLevel> computeMax) {
- AndroidApiLevel computedLevel = appView.options().minApiLevel;
+ AppView<?> appView, Map<DexReference, AndroidApiLevel> apiLevelMap) {
+ AndroidApiLevel minApiLevel = appView.options().minApiLevel;
+ AndroidApiLevel apiLevel = minApiLevel;
for (DexType type : getReferencedBaseTypes(appView.dexItemFactory())) {
- computedLevel = computeMax.apply(type, computedLevel);
+ apiLevel = apiLevel.max(apiLevelMap.getOrDefault(type, minApiLevel));
}
- return computedLevel;
+ return apiLevel;
}
}
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 62ed777..f93437e 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
@@ -4,10 +4,10 @@
package com.android.tools.r8.graph.analysis;
-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.DexMember;
+import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
@@ -16,17 +16,19 @@
import com.android.tools.r8.ir.optimize.info.MemberOptimizationInfo;
import com.android.tools.r8.shaking.DefaultEnqueuerUseRegistry;
import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.Map;
public class ApiModelAnalysis extends EnqueuerAnalysis {
private final AppView<?> appView;
private final AndroidApiLevel minApiLevel;
- private final AndroidApiReferenceLevelCache referenceLevelCache;
+ private final Map<DexReference, AndroidApiLevel> referenceToApiLevelMap;
- public ApiModelAnalysis(AppView<?> appView, AndroidApiReferenceLevelCache referenceLevelCache) {
+ public ApiModelAnalysis(
+ AppView<?> appView, Map<DexReference, AndroidApiLevel> referenceToApiLevelMap) {
this.appView = appView;
this.minApiLevel = appView.options().minApiLevel;
- this.referenceLevelCache = referenceLevelCache;
+ this.referenceToApiLevelMap = referenceToApiLevelMap;
}
@Override
@@ -44,13 +46,6 @@
@Override
public void processTracedCode(ProgramMethod method, DefaultEnqueuerUseRegistry registry) {
assert registry.getMaxApiReferenceLevel().isGreaterThanOrEqualTo(minApiLevel);
- if (appView.options().apiModelingOptions().tracedMethodApiLevelCallback != null) {
- appView
- .options()
- .apiModelingOptions()
- .tracedMethodApiLevelCallback
- .accept(method.getMethodReference(), registry.getMaxApiReferenceLevel());
- }
setApiLevelForMember(method.getDefinition(), registry.getMaxApiReferenceLevel());
}
@@ -82,6 +77,6 @@
}
private AndroidApiLevel computeApiLevelForReferencedTypes(DexMember<?, ?> member) {
- return member.computeApiLevelForReferencedTypes(appView, referenceLevelCache::lookupMax);
+ return member.computeApiLevelForReferencedTypes(appView, referenceToApiLevelMap);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoEnqueuerUseRegistry.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoEnqueuerUseRegistry.java
index ecd958d..f8aae86 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoEnqueuerUseRegistry.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoEnqueuerUseRegistry.java
@@ -20,7 +20,7 @@
import com.android.tools.r8.shaking.EnqueuerUseRegistryFactory;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.util.ListIterator;
-import java.util.function.BiFunction;
+import java.util.Map;
public class ProtoEnqueuerUseRegistry extends DefaultEnqueuerUseRegistry {
@@ -32,7 +32,7 @@
AppView<? extends AppInfoWithClassHierarchy> appView,
ProgramMethod currentMethod,
Enqueuer enqueuer,
- BiFunction<DexReference, AndroidApiLevel, AndroidApiLevel> apiLevelReferenceMap) {
+ Map<DexReference, AndroidApiLevel> apiLevelReferenceMap) {
super(appView, currentMethod, enqueuer, apiLevelReferenceMap);
this.references = appView.protoShrinker().references;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java b/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
index 8a3a7e3..da86fe5 100644
--- a/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
+++ b/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
@@ -19,21 +19,21 @@
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.util.ListIterator;
-import java.util.function.BiFunction;
+import java.util.Map;
public class DefaultEnqueuerUseRegistry extends UseRegistry {
protected final AppView<? extends AppInfoWithClassHierarchy> appView;
private final ProgramMethod context;
protected final Enqueuer enqueuer;
- private final BiFunction<DexReference, AndroidApiLevel, AndroidApiLevel> apiReferenceMapping;
+ private final Map<DexReference, AndroidApiLevel> apiReferenceMapping;
private AndroidApiLevel maxApiReferenceLevel;
public DefaultEnqueuerUseRegistry(
AppView<? extends AppInfoWithClassHierarchy> appView,
ProgramMethod context,
Enqueuer enqueuer,
- BiFunction<DexReference, AndroidApiLevel, AndroidApiLevel> apiReferenceMapping) {
+ Map<DexReference, AndroidApiLevel> apiReferenceMapping) {
super(appView.dexItemFactory());
this.appView = appView;
this.context = context;
@@ -188,13 +188,14 @@
private void setMaxApiReferenceLevel(DexReference reference) {
if (reference.isDexMember()) {
- maxApiReferenceLevel =
+ this.maxApiReferenceLevel =
maxApiReferenceLevel.max(
reference
.asDexMember()
.computeApiLevelForReferencedTypes(appView, apiReferenceMapping));
}
- maxApiReferenceLevel = apiReferenceMapping.apply(reference, maxApiReferenceLevel);
+ this.maxApiReferenceLevel =
+ maxApiReferenceLevel.max(apiReferenceMapping.getOrDefault(reference, maxApiReferenceLevel));
}
public AndroidApiLevel getMaxApiReferenceLevel() {
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index ea9b2d7..abb6523 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -15,7 +15,6 @@
import static java.util.Collections.emptySet;
import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.androidapi.AndroidApiReferenceLevelCache;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.code.CfOrDexInstruction;
@@ -121,6 +120,7 @@
import com.android.tools.r8.shaking.ScopedDexMethodSet.AddMethodIfMoreVisibleResult;
import com.android.tools.r8.synthesis.SyntheticItems.SynthesizingContextOracle;
import com.android.tools.r8.utils.Action;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.IteratorUtils;
import com.android.tools.r8.utils.ListUtils;
@@ -255,7 +255,7 @@
private final Set<DexReference> identifierNameStrings = Sets.newIdentityHashSet();
- private final AndroidApiReferenceLevelCache apiReferenceLevelCache;
+ private final Map<DexReference, AndroidApiLevel> referenceToApiLevelMap;
/**
* Tracks the dependency between a method and the super-method it calls, if any. Used to make
@@ -473,7 +473,10 @@
} else {
desugaredLibraryWrapperAnalysis = null;
}
- apiReferenceLevelCache = AndroidApiReferenceLevelCache.create(appView);
+ referenceToApiLevelMap = new IdentityHashMap<>();
+ if (options.apiModelingOptions().enableApiCallerIdentification) {
+ options.apiModelingOptions().appendToApiLevelMap(referenceToApiLevelMap, dexItemFactory);
+ }
}
private AppInfoWithClassHierarchy appInfo() {
@@ -3025,7 +3028,7 @@
registerAnalysis(new GenericSignatureEnqueuerAnalysis(enqueuerDefinitionSupplier));
}
if (appView.options().apiModelingOptions().enableApiCallerIdentification) {
- registerAnalysis(new ApiModelAnalysis(appView, apiReferenceLevelCache));
+ registerAnalysis(new ApiModelAnalysis(appView, referenceToApiLevelMap));
}
if (mode.isInitialTreeShaking()) {
// This is simulating the effect of the "root set" applied rules.
@@ -3941,7 +3944,7 @@
void traceCode(ProgramMethod method) {
DefaultEnqueuerUseRegistry registry =
- useRegistryFactory.create(appView, method, this, apiReferenceLevelCache::lookupMax);
+ useRegistryFactory.create(appView, method, this, referenceToApiLevelMap);
method.registerCodeReferences(registry);
// Notify analyses.
analyses.forEach(analysis -> analysis.processTracedCode(method, registry));
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerUseRegistryFactory.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerUseRegistryFactory.java
index def9a41..6bd8473 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerUseRegistryFactory.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerUseRegistryFactory.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.utils.AndroidApiLevel;
-import java.util.function.BiFunction;
+import java.util.Map;
public interface EnqueuerUseRegistryFactory {
@@ -17,5 +17,5 @@
AppView<? extends AppInfoWithClassHierarchy> appView,
ProgramMethod currentMethod,
Enqueuer enqueuer,
- BiFunction<DexReference, AndroidApiLevel, AndroidApiLevel> apiLevelReferenceMap);
+ Map<DexReference, AndroidApiLevel> apiLevelReferenceMap);
}
diff --git a/src/main/java/com/android/tools/r8/utils/EntryUtils.java b/src/main/java/com/android/tools/r8/utils/EntryUtils.java
deleted file mode 100644
index e1d28b1..0000000
--- a/src/main/java/com/android/tools/r8/utils/EntryUtils.java
+++ /dev/null
@@ -1,15 +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.utils;
-
-import java.util.Map.Entry;
-import java.util.function.BiFunction;
-
-public class EntryUtils {
-
- public static <K, V, R> R accept(Entry<K, V> entry, BiFunction<K, V, R> consumer) {
- return consumer.apply(entry.getKey(), entry.getValue());
- }
-}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 5af6963..0a1fcc7 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -14,7 +14,6 @@
import com.android.tools.r8.ProgramConsumer;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.Version;
-import com.android.tools.r8.androidapi.AndroidApiClass;
import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Backend;
@@ -38,6 +37,7 @@
import com.android.tools.r8.graph.DexLibraryClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.classmerging.VerticallyMergedClasses;
@@ -52,10 +52,10 @@
import com.android.tools.r8.naming.MapVersion;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
-import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.references.TypeReference;
import com.android.tools.r8.repackaging.Repackaging.DefaultRepackagingConfiguration;
import com.android.tools.r8.repackaging.Repackaging.RepackagingConfiguration;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -84,12 +84,10 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -1321,68 +1319,21 @@
// A mapping from references to the api-level introducing them.
public Map<MethodReference, AndroidApiLevel> methodApiMapping = new HashMap<>();
public Map<FieldReference, AndroidApiLevel> fieldApiMapping = new HashMap<>();
- public Map<ClassReference, AndroidApiLevel> classApiMapping = new HashMap<>();
- public BiConsumer<MethodReference, AndroidApiLevel> tracedMethodApiLevelCallback = null;
+ public Map<TypeReference, AndroidApiLevel> typeApiMapping = new HashMap<>();
public boolean enableApiCallerIdentification = false;
- public void visitMockedApiReferences(BiConsumer<ClassReference, AndroidApiClass> consumer) {
- if (methodApiMapping.isEmpty() && fieldApiMapping.isEmpty() && classApiMapping.isEmpty()) {
- return;
- }
- Set<ClassReference> classReferences = new HashSet<>(classApiMapping.keySet());
- methodApiMapping
- .keySet()
- .forEach(methodReference -> classReferences.add(methodReference.getHolderClass()));
- fieldApiMapping
- .keySet()
- .forEach(methodReference -> classReferences.add(methodReference.getHolderClass()));
- classReferences.forEach(
- classReference -> {
- consumer.accept(
- classReference,
- new AndroidApiClass(classReference) {
- @Override
- public AndroidApiLevel getApiLevel() {
- return classApiMapping.getOrDefault(classReference, AndroidApiLevel.B);
- }
-
- @Override
- public int getMemberCount() {
- return 0;
- }
-
- @Override
- public TraversalContinuation visitFields(
- BiFunction<FieldReference, AndroidApiLevel, TraversalContinuation> visitor) {
- for (Entry<FieldReference, AndroidApiLevel> entry :
- fieldApiMapping.entrySet()) {
- if (!entry.getKey().getHolderClass().equals(classReference)) {
- continue;
- }
- if (EntryUtils.accept(entry, visitor).shouldBreak()) {
- return TraversalContinuation.BREAK;
- }
- }
- return TraversalContinuation.CONTINUE;
- }
-
- @Override
- public TraversalContinuation visitMethods(
- BiFunction<MethodReference, AndroidApiLevel, TraversalContinuation> visitor) {
- for (Entry<MethodReference, AndroidApiLevel> entry :
- methodApiMapping.entrySet()) {
- if (!entry.getKey().getHolderClass().equals(classReference)) {
- continue;
- }
- if (EntryUtils.accept(entry, visitor).shouldBreak()) {
- return TraversalContinuation.BREAK;
- }
- }
- return TraversalContinuation.CONTINUE;
- }
- });
- });
+ public void appendToApiLevelMap(
+ Map<DexReference, AndroidApiLevel> apiLevelMap, DexItemFactory factory) {
+ methodApiMapping.forEach(
+ (methodReference, apiLevel) ->
+ apiLevelMap.put(factory.createMethod(methodReference), apiLevel));
+ fieldApiMapping.forEach(
+ (fieldReference, apiLevel) ->
+ apiLevelMap.put(factory.createField(fieldReference), apiLevel));
+ typeApiMapping.forEach(
+ (typeReference, apiLevel) ->
+ apiLevelMap.put(factory.createType(typeReference.getDescriptor()), apiLevel));
}
}
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderGenerator.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderGenerator.java
index 9aa8f4d..bc25cd4 100644
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderGenerator.java
+++ b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderGenerator.java
@@ -94,12 +94,10 @@
.setClassDescriptor(getApiClassDescriptor(apiClass))
.addMethodTransformer(getInitTransformer(apiClass))
.addMethodTransformer(getApiLevelTransformer(apiClass))
- .addMethodTransformer(getGetMemberCountTransformer(apiClass))
.addMethodTransformer(getVisitFieldsTransformer(apiClass))
.addMethodTransformer(getVisitMethodsTransformer(apiClass))
.removeMethods(MethodPredicate.onName("placeHolderForInit"))
.removeMethods(MethodPredicate.onName("placeHolderForGetApiLevel"))
- .removeMethods(MethodPredicate.onName("placeHolderForGetMemberCount"))
.removeMethods(MethodPredicate.onName("placeHolderForVisitFields"))
.removeMethods(MethodPredicate.onName("placeHolderForVisitMethods"))
.transform());
@@ -172,16 +170,6 @@
});
}
- // The transformer below changes AndroidApiDatabaseClassTemplate.getMemberCount from:
- // return placeHolderForGetMemberCount();
- // into
- // return <memberCount>;
- private static MethodTransformer getGetMemberCountTransformer(ParsedApiClass apiClass) {
- return replaceCode(
- "placeHolderForGetMemberCount",
- transformer -> transformer.visitLdcInsn(apiClass.getMemberCount()));
- }
-
// The transformer below changes AndroidApiDatabaseClassTemplate.visitFields from:
// placeHolder();
// return TraversalContinuation.CONTINUE;
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderGeneratorTest.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderGeneratorTest.java
index 6d46bfd..d85e3e5 100644
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderGeneratorTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderGeneratorTest.java
@@ -225,7 +225,12 @@
ZipUtils.unzip(
ToolHelper.DEPS.toString(),
tempDeps.toFile(),
- entry -> !entry.getName().startsWith("com/android/tools/r8/apimodel/"));
+ entry -> {
+ if (entry.getName().startsWith("com/android/tools/r8/apimodel/")) {
+ return false;
+ }
+ return true;
+ });
Path modifiedDeps = Files.createTempFile("modified_deps", ".jar");
ZipUtils.zip(modifiedDeps, tempDeps);
return modifiedDeps;
@@ -237,7 +242,6 @@
apiClass -> {
expected.add(apiClass.getClassReference().getDescriptor());
expected.add(apiClass.getApiLevel().getName());
- expected.add(apiClass.getMemberCount() + "");
BooleanBox added = new BooleanBox(false);
apiClass.visitFieldReferences(
(apiLevel, fieldReferences) -> {
@@ -288,7 +292,6 @@
if (apiClass != null) {
System.out.println(descriptor);
System.out.println(apiClass.getApiLevel().getName());
- System.out.println(apiClass.getMemberCount());
apiClass.visitFields(
(reference, apiLevel) -> {
System.out.println(reference.getFieldType().getDescriptor());
@@ -319,7 +322,6 @@
if (apiClass != null) {
System.out.println(descriptor);
System.out.println(apiClass.getApiLevel().getName());
- System.out.println(apiClass.getMemberCount());
apiClass.visitFields(
(reference, apiLevel) -> {
System.out.println(reference.getFieldType().getDescriptor());
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseClassTemplate.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseClassTemplate.java
index faefd62..2598898 100644
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseClassTemplate.java
+++ b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseClassTemplate.java
@@ -27,12 +27,6 @@
}
@Override
- public int getMemberCount() {
- // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
- return placeHolderForGetMemberCount();
- }
-
- @Override
public TraversalContinuation visitFields(
BiFunction<FieldReference, AndroidApiLevel, TraversalContinuation> visitor) {
// Code added dynamically in AndroidApiDatabaseBuilderGenerator.
@@ -56,10 +50,6 @@
return null;
}
- private static int placeHolderForGetMemberCount() {
- return 0;
- }
-
private static void placeHolderForVisitFields() {}
private static void placeHolderForVisitMethods() {}
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiVersionsXmlParser.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiVersionsXmlParser.java
index dbb71d3..c904dff 100644
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiVersionsXmlParser.java
+++ b/src/test/java/com/android/tools/r8/apimodel/AndroidApiVersionsXmlParser.java
@@ -135,11 +135,6 @@
private final TreeMap<AndroidApiLevel, List<FieldReference>> fieldReferences = new TreeMap<>();
private final Map<AndroidApiLevel, List<MethodReference>> methodReferences = new TreeMap<>();
- private ParsedApiClass(ClassReference classReference, AndroidApiLevel apiLevel) {
- this.classReference = classReference;
- this.apiLevel = apiLevel;
- }
-
public ClassReference getClassReference() {
return classReference;
}
@@ -148,8 +143,9 @@
return apiLevel;
}
- public int getMemberCount() {
- return fieldReferences.size() + methodReferences.size();
+ private ParsedApiClass(ClassReference classReference, AndroidApiLevel apiLevel) {
+ this.classReference = classReference;
+ this.apiLevel = apiLevel;
}
private void register(FieldReference reference, AndroidApiLevel apiLevel) {
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelClassMergingWithDifferentApiFieldsTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelClassMergingWithDifferentApiFieldsTest.java
index 2f4e83c..5d0c0b8 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelClassMergingWithDifferentApiFieldsTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelClassMergingWithDifferentApiFieldsTest.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.apimodel;
-import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
+import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForType;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
@@ -45,7 +45,7 @@
.addHorizontallyMergedClassesInspector(
inspector -> inspector.assertClassesMerged(A.class, B.class))
.apply(ApiModelingTestHelper::enableApiCallerIdentification)
- .apply(setMockApiLevelForClass(Api.class, AndroidApiLevel.L_MR1))
+ .apply(setMockApiLevelForType(Api.class, AndroidApiLevel.L_MR1))
.compile()
.addRunClasspathClasses(Api.class)
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelInlineMethodWithApiTypeTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelInlineMethodWithApiTypeTest.java
index 03b2f3e..f6996e9 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelInlineMethodWithApiTypeTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelInlineMethodWithApiTypeTest.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.apimodel;
-import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
+import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForType;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.verifyThat;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
@@ -46,7 +46,7 @@
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(Main.class)
.enableNoHorizontalClassMergingAnnotations()
- .apply(setMockApiLevelForClass(ApiType.class, AndroidApiLevel.L_MR1))
+ .apply(setMockApiLevelForType(ApiType.class, AndroidApiLevel.L_MR1))
.apply(ApiModelingTestHelper::enableApiCallerIdentification)
.compile()
.addRunClasspathClasses(ApiType.class)
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelInstanceFieldTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelInstanceFieldTest.java
index a1ecb6a..c7b2b1c 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelInstanceFieldTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelInstanceFieldTest.java
@@ -4,16 +4,15 @@
package com.android.tools.r8.apimodel;
-import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForField;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.verifyThat;
-import static com.android.tools.r8.utils.AndroidApiLevel.L_MR1;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;
@@ -48,11 +47,12 @@
.addKeepMainRule(Main.class)
.enableInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
- .apply(setMockApiLevelForField(apiField, L_MR1))
- .apply(setMockApiLevelForDefaultInstanceInitializer(Api.class, L_MR1))
+ .apply(setMockApiLevelForField(apiField, AndroidApiLevel.L_MR1))
.apply(ApiModelingTestHelper::enableApiCallerIdentification)
.compile()
- .inspect(verifyThat(parameters, apiCaller).inlinedIntoFromApiLevel(apiCallerCaller, L_MR1))
+ .inspect(
+ verifyThat(parameters, apiCaller)
+ .inlinedIntoFromApiLevel(apiCallerCaller, AndroidApiLevel.L_MR1))
.addRunClasspathClasses(Api.class)
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines("Hello World!");
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelSuperTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelSuperTest.java
index e1cf2e2..7d6230b 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelSuperTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelSuperTest.java
@@ -4,19 +4,16 @@
package com.android.tools.r8.apimodel;
-import static com.android.tools.r8.apimodel.ApiModelingTestHelper.addTracedApiReferenceLevelCallBack;
-import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForMethod;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.verifyThat;
-import static org.junit.Assert.assertEquals;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
+import com.android.tools.r8.NoVerticalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.lang.reflect.Method;
import org.junit.Test;
@@ -44,36 +41,25 @@
Method apiCaller = ApiCaller.class.getDeclaredMethod("apiLevel22");
Method apiCallerCaller = A.class.getDeclaredMethod("noApiCall");
testForR8(parameters.getBackend())
- .addProgramClasses(ApiCaller.class, A.class, Main.class)
- .addLibraryClasses(Api.class)
- .addDefaultRuntimeLibrary(parameters)
+ .addInnerClasses(getClass())
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(Main.class)
.enableInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
.enableNeverClassInliningAnnotations()
+ .enableNoVerticalClassMergingAnnotations()
.apply(setMockApiLevelForMethod(apiMethod, AndroidApiLevel.L_MR1))
- .apply(setMockApiLevelForDefaultInstanceInitializer(Api.class, AndroidApiLevel.L_MR1))
.apply(ApiModelingTestHelper::enableApiCallerIdentification)
- .apply(
- addTracedApiReferenceLevelCallBack(
- (method, apiLevel) -> {
- if (Reference.methodFromMethod(apiCaller).equals(method)) {
- if (parameters.isCfRuntime()) {
- assertEquals(AndroidApiLevel.L_MR1, apiLevel);
- } else {
- assertEquals(AndroidApiLevel.L_MR1.max(parameters.getApiLevel()), apiLevel);
- }
- }
- }))
.compile()
- // We do not inline overrides calling super.
- .inspect(verifyThat(parameters, apiCaller).notInlinedInto(apiCallerCaller))
+ .inspect(
+ verifyThat(parameters, apiCaller)
+ .inlinedIntoFromApiLevel(apiCallerCaller, AndroidApiLevel.L_MR1))
.addRunClasspathClasses(Api.class)
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines("A::noApiCall", "ApiCaller::apiLevel22", "Api::apiLevel22");
}
+ @NoVerticalClassMerging
public static class Api {
void apiLevel22() {
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelVirtualTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelVirtualTest.java
index f09f09d..d87ed82 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelVirtualTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelVirtualTest.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.apimodel;
import static com.android.tools.r8.apimodel.ApiModelNoInliningOfHigherApiLevelVirtualTest.ApiCaller.callVirtualMethod;
-import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForMethod;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.verifyThat;
@@ -49,7 +48,6 @@
.enableInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
.apply(setMockApiLevelForMethod(apiMethod, AndroidApiLevel.L_MR1))
- .apply(setMockApiLevelForDefaultInstanceInitializer(Api.class, AndroidApiLevel.L_MR1))
.apply(ApiModelingTestHelper::enableApiCallerIdentification)
.compile()
.inspect(
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelVerticalMergingOfSuperClassTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelVerticalMergingOfSuperClassTest.java
index 6cc4d9d..80e213e 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelVerticalMergingOfSuperClassTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelVerticalMergingOfSuperClassTest.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.apimodel;
-import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
+import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForType;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -44,7 +44,7 @@
.addKeepMainRule(Main.class)
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
- .apply(setMockApiLevelForClass(Api.class, AndroidApiLevel.L_MR1))
+ .apply(setMockApiLevelForType(Api.class, AndroidApiLevel.L_MR1))
.apply(ApiModelingTestHelper::enableApiCallerIdentification)
.compile()
.inspect(
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelingTestHelper.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelingTestHelper.java
index 184536c..33d1deb 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelingTestHelper.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelingTestHelper.java
@@ -11,17 +11,14 @@
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.ThrowingConsumer;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.CodeMatchers;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
-import com.google.common.collect.ImmutableList;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.util.function.BiConsumer;
public abstract class ApiModelingTestHelper {
@@ -39,23 +36,6 @@
}
static <T extends TestCompilerBuilder<?, ?, ?, ?, ?>>
- ThrowableConsumer<T> setMockApiLevelForDefaultInstanceInitializer(
- Class<?> clazz, AndroidApiLevel apiLevel) {
- return compilerBuilder -> {
- compilerBuilder.addOptionsModification(
- options -> {
- options
- .apiModelingOptions()
- .methodApiMapping
- .put(
- Reference.method(
- Reference.classFromClass(clazz), "<init>", ImmutableList.of(), null),
- apiLevel);
- });
- };
- }
-
- static <T extends TestCompilerBuilder<?, ?, ?, ?, ?>>
ThrowableConsumer<T> setMockApiLevelForField(Field field, AndroidApiLevel apiLevel) {
return compilerBuilder -> {
compilerBuilder.addOptionsModification(
@@ -68,14 +48,14 @@
};
}
- static <T extends TestCompilerBuilder<?, ?, ?, ?, ?>>
- ThrowableConsumer<T> setMockApiLevelForClass(Class<?> clazz, AndroidApiLevel apiLevel) {
+ static <T extends TestCompilerBuilder<?, ?, ?, ?, ?>> ThrowableConsumer<T> setMockApiLevelForType(
+ Class<?> clazz, AndroidApiLevel apiLevel) {
return compilerBuilder -> {
compilerBuilder.addOptionsModification(
options -> {
options
.apiModelingOptions()
- .classApiMapping
+ .typeApiMapping
.put(Reference.classFromClass(clazz), apiLevel);
});
};
@@ -88,17 +68,6 @@
});
}
- static <T extends TestCompilerBuilder<?, ?, ?, ?, ?>>
- ThrowableConsumer<T> addTracedApiReferenceLevelCallBack(
- BiConsumer<MethodReference, AndroidApiLevel> consumer) {
- return compilerBuilder -> {
- compilerBuilder.addOptionsModification(
- options -> {
- options.apiModelingOptions().tracedMethodApiLevelCallback = consumer;
- });
- };
- }
-
static ApiModelingMethodVerificationHelper verifyThat(TestParameters parameters, Method method) {
return new ApiModelingMethodVerificationHelper(parameters, method);
}
@@ -120,7 +89,7 @@
: notInlinedInto(method);
}
- protected ThrowingConsumer<CodeInspector, Exception> notInlinedInto(Method method) {
+ private ThrowingConsumer<CodeInspector, Exception> notInlinedInto(Method method) {
return inspector -> {
MethodSubject candidate = inspector.method(methodOfInterest);
assertThat(candidate, isPresent());
diff --git a/third_party/android_jar/api-database.tar.gz.sha1 b/third_party/android_jar/api-database.tar.gz.sha1
index 6336e23..84abf49 100644
--- a/third_party/android_jar/api-database.tar.gz.sha1
+++ b/third_party/android_jar/api-database.tar.gz.sha1
@@ -1 +1 @@
-be72aeca006f1aba8b1fe4d9c3ff4c0e76259960
\ No newline at end of file
+e4da4b29079ac393e0012e7676dcca0799841e29
\ No newline at end of file