Use builder in Nest lens
Bug:147204126
Change-Id: I728852c38edbc3f8d16ee736dddb4028e0a75f75
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLense.java b/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLense.java
index babdbae..9fca058 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLense.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLense.java
@@ -41,9 +41,9 @@
assert methodMap instanceof IdentityHashMap;
assert getFieldMap instanceof IdentityHashMap;
assert putFieldMap instanceof IdentityHashMap;
+ this.nestConstructorType = nestConstructorType;
this.getFieldMap = getFieldMap;
this.putFieldMap = putFieldMap;
- this.nestConstructorType = nestConstructorType;
}
private DexMethod lookupFieldForMethod(
@@ -111,11 +111,8 @@
@Override
public GraphLenseLookupResult lookupMethod(
DexMethod method, DexMethod context, Invoke.Type type) {
- DexMethod previousContext =
- originalMethodSignatures != null
- ? originalMethodSignatures.getOrDefault(context, context)
- : context;
- GraphLenseLookupResult previous = previousLense.lookupMethod(method, previousContext, type);
+ assert originalMethodSignatures == null;
+ GraphLenseLookupResult previous = previousLense.lookupMethod(method, context, type);
DexMethod bridge = methodMap.get(previous.getMethod());
if (bridge == null) {
return previous;
@@ -130,4 +127,31 @@
return new GraphLenseLookupResult(bridge, Invoke.Type.STATIC);
}
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder extends NestedGraphLense.Builder {
+
+ private Map<DexField, DexMethod> getFieldMap = new IdentityHashMap<>();
+ private Map<DexField, DexMethod> putFieldMap = new IdentityHashMap<>();
+
+ public void mapGetField(DexField from, DexMethod to) {
+ getFieldMap.put(from, to);
+ }
+
+ public void mapPutField(DexField from, DexMethod to) {
+ putFieldMap.put(from, to);
+ }
+
+ public GraphLense build(AppView<?> appView, DexType nestConstructorType) {
+ assert typeMap.isEmpty();
+ assert fieldMap.isEmpty();
+ if (getFieldMap.isEmpty() && methodMap.isEmpty() && putFieldMap.isEmpty()) {
+ return appView.graphLense();
+ }
+ return new NestedPrivateMethodLense(
+ appView, nestConstructorType, methodMap, getFieldMap, putFieldMap, appView.graphLense());
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/R8NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/R8NestBasedAccessDesugaring.java
index a4642cd..1a6c365 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/R8NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/R8NestBasedAccessDesugaring.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
@@ -16,13 +15,13 @@
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.collect.Sets;
import java.util.ArrayList;
-import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
+import java.util.function.BiConsumer;
// Summary:
// - Computes all the live nests reachable from Program Classes (Sequential), each time a
@@ -31,10 +30,6 @@
// for the lens (Sequential)
public class R8NestBasedAccessDesugaring extends NestBasedAccessDesugaring {
- private final Map<DexMethod, DexMethod> lensBridges = new IdentityHashMap<>();
- private final Map<DexField, DexMethod> lensGetFieldBridges = new IdentityHashMap<>();
- private final Map<DexField, DexMethod> lensPutFieldBridges = new IdentityHashMap<>();
-
public R8NestBasedAccessDesugaring(AppView<?> appView) {
super(appView);
}
@@ -44,43 +39,27 @@
assert !appView.options().canUseNestBasedAccess()
|| appView.options().testing.enableForceNestBasedAccessDesugaringForTest;
computeAndProcessNestsConcurrently(executorService);
- addDeferredBridgesAndMapMethods();
+ NestedPrivateMethodLense.Builder lensBuilder = NestedPrivateMethodLense.builder();
+ addDeferredBridgesAndMapMethods(lensBuilder);
clearNestAttributes();
- if (nothingToMap()) {
- return appView.graphLense();
- }
synthesizeNestConstructor(appBuilder);
- return new NestedPrivateMethodLense(
- appView,
- getNestConstructorType(),
- lensBridges,
- lensGetFieldBridges,
- lensPutFieldBridges,
- appView.graphLense());
+ return lensBuilder.build(appView, getNestConstructorType());
}
- private boolean nothingToMap() {
- return lensBridges.isEmpty() && lensGetFieldBridges.isEmpty() && lensPutFieldBridges.isEmpty();
- }
-
- private void addDeferredBridgesAndMapMethods() {
+ private void addDeferredBridgesAndMapMethods(NestedPrivateMethodLense.Builder lensBuilder) {
// Here we add the bridges and we fill the lens map.
- // The lens map are different than the original map since
- // they refer DexMethod and not DexEncodedMethod (so they can be long lived without issues),
- // and since they do not require synchronization (they are only read in the lens).
- // We cannot easily do this concurrently since methods are added to classes.
- addDeferredBridgesAndMapMethods(bridges, lensBridges);
- addDeferredBridgesAndMapMethods(getFieldBridges, lensGetFieldBridges);
- addDeferredBridgesAndMapMethods(putFieldBridges, lensPutFieldBridges);
+ addDeferredBridgesAndMapMethods(bridges, lensBuilder::map);
+ addDeferredBridgesAndMapMethods(getFieldBridges, lensBuilder::mapGetField);
+ addDeferredBridgesAndMapMethods(putFieldBridges, lensBuilder::mapPutField);
}
private <E> void addDeferredBridgesAndMapMethods(
- Map<E, DexEncodedMethod> bridges, Map<E, DexMethod> map) {
+ Map<E, DexEncodedMethod> bridges, BiConsumer<E, DexMethod> lensInserter) {
for (Map.Entry<E, DexEncodedMethod> entry : bridges.entrySet()) {
DexClass holder = definitionFor(entry.getValue().method.holder);
assert holder != null && holder.isProgramClass();
holder.asProgramClass().addMethod(entry.getValue());
- map.put(entry.getKey(), entry.getValue().method);
+ lensInserter.accept(entry.getKey(), entry.getValue().method);
}
bridges.clear();
}