[ApiModel] Do not stub references when merging
Also, do not process when the type is prefixed with java. Adding this check will remove some of the contention on the seen set.
Bug: b/273232160
Change-Id: I73cb44c2bbe411841554a2e55d45e1086c996163
diff --git a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
index 261497d..8bbfcfd 100644
--- a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
+++ b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
@@ -24,10 +24,12 @@
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.synthesis.CommittedItems;
import com.android.tools.r8.synthesis.SyntheticItems;
+import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.WorkList;
import com.google.common.collect.Sets;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -58,7 +60,16 @@
public void run(ExecutorService executorService) throws ExecutionException {
if (appView.options().isGeneratingDex()
&& appView.options().apiModelingOptions().enableStubbingOfClasses) {
- ThreadUtils.processItems(appView.appInfo().classes(), this::processClass, executorService);
+ Collection<DexProgramClass> classes =
+ ListUtils.filter(
+ appView.appInfo().classes(), DexProgramClass::originatesFromClassResource);
+ // Finding super types is really fast so no need to pay the overhead of threading if the
+ // number of classes is low.
+ if (classes.size() > 2) {
+ ThreadUtils.processItems(classes, this::processClass, executorService);
+ } else {
+ classes.forEach(this::processClass);
+ }
}
if (!libraryClassesToMock.isEmpty()) {
libraryClassesToMock.forEach(
@@ -98,6 +109,7 @@
}
public void processClass(DexProgramClass clazz) {
+ assert clazz.originatesFromClassResource();
if (isAlreadyOutlined(clazz)) {
return;
}
@@ -124,7 +136,7 @@
}
private void findReferencedLibraryClasses(DexType type, DexProgramClass context) {
- if (!type.isClassType()) {
+ if (!type.isClassType() || isJavaType(type)) {
return;
}
WorkList<DexType> workList = WorkList.newIdentityWorkList(type, seenTypes);
@@ -147,17 +159,18 @@
}
}
+ private boolean isJavaType(DexType type) {
+ return type == appView.dexItemFactory().objectType
+ || type.getDescriptor().startsWith(appView.dexItemFactory().javaDescriptorPrefix);
+ }
+
private void mockMissingLibraryClass(
DexLibraryClass libraryClass,
ThrowExceptionCode throwExceptionCode,
ApiReferenceStubberEventConsumer eventConsumer) {
DexItemFactory factory = appView.dexItemFactory();
// Do not stub the anything starting with java (including the object type).
- if (libraryClass.getType() == appView.dexItemFactory().objectType
- || libraryClass
- .getType()
- .getDescriptor()
- .startsWith(appView.dexItemFactory().javaDescriptorPrefix)) {
+ if (isJavaType(libraryClass.getType())) {
return;
}
// Check if desugared library will bridge the type.