Simple cleanup of access to methods and fields in DexClass.
Bug:
Change-Id: I74e211e5ee13b6a68404ddfbd331ba92caa63d30
diff --git a/src/main/java/com/android/tools/r8/PrintClassList.java b/src/main/java/com/android/tools/r8/PrintClassList.java
index 6c49769..bc274a8 100644
--- a/src/main/java/com/android/tools/r8/PrintClassList.java
+++ b/src/main/java/com/android/tools/r8/PrintClassList.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Timing;
+
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
@@ -46,39 +47,32 @@
for (DexProgramClass clazz : application.classes()) {
System.out.print(maybeDeobfuscateType(map, clazz.type));
System.out.println();
- printMethods(clazz.directMethods(), map);
- printMethods(clazz.virtualMethods(), map);
- printFields(clazz.staticFields(), map);
- printFields(clazz.instanceFields(), map);
+ clazz.forEachMethod(method -> printMethod(method, map));
+ clazz.forEachField(field -> printField(field, map));
}
executorService.shutdown();
}
- private static void printMethods(DexEncodedMethod[] methods, ClassNameMapper map) {
- for (DexEncodedMethod encodedMethod : methods) {
- DexMethod method = encodedMethod.method;
-
- if (map != null) {
- System.out.println(map.originalNameOf(method));
- } else {
- // Detour via Signature to get the same formatting.
- MethodSignature signature = MethodSignature.fromDexMethod(method);
- System.out.println(method.holder.toSourceString() + " " + signature);
- }
+ private static void printMethod(DexEncodedMethod encodedMethod, ClassNameMapper map) {
+ DexMethod method = encodedMethod.method;
+ if (map != null) {
+ System.out.println(map.originalNameOf(method));
+ } else {
+ // Detour via Signature to get the same formatting.
+ MethodSignature signature = MethodSignature.fromDexMethod(method);
+ System.out.println(method.holder.toSourceString() + " " + signature);
}
}
- private static void printFields(DexEncodedField[] fields, ClassNameMapper map) {
- for (DexEncodedField encodedField : fields) {
- DexField field = encodedField.field;
- if (map != null) {
- System.out.println(map.originalNameOf(field));
- } else {
- // Detour via Signature to get the same formatting.
- FieldSignature signature = new FieldSignature(field.name.toSourceString(),
- field.type.toSourceString());
- System.out.println(field.clazz.toSourceString() + " " + signature);
- }
+ private static void printField(DexEncodedField encodedField, ClassNameMapper map) {
+ DexField field = encodedField.field;
+ if (map != null) {
+ System.out.println(map.originalNameOf(field));
+ } else {
+ // Detour via Signature to get the same formatting.
+ FieldSignature signature = new FieldSignature(field.name.toSourceString(),
+ field.type.toSourceString());
+ System.out.println(field.clazz.toSourceString() + " " + signature);
}
}
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index a215ece..b56f712 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -5,6 +5,8 @@
import static com.android.tools.r8.utils.LebUtils.sizeAsUleb128;
+import com.google.common.collect.Sets;
+
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppInfo;
@@ -49,11 +51,12 @@
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.LebUtils;
-import com.google.common.collect.Sets;
+
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
+
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
@@ -153,17 +156,14 @@
return this;
}
- private void rewriteCodeWithJumboStrings(IRConverter converter, DexEncodedMethod[] methods) {
- for (int i = 0; i < methods.length; i++) {
- DexEncodedMethod method = methods[i];
- if (method.getCode() == null) {
- continue;
- }
- DexCode code = method.getCode().asDexCode();
- if (code.highestSortingString != null) {
- if (mapping.getOffsetFor(code.highestSortingString) > Constants.MAX_NON_JUMBO_INDEX) {
- converter.processJumboStrings(method, mapping.getFirstJumboString());
- }
+ private void rewriteCodeWithJumboStrings(IRConverter converter, DexEncodedMethod method) {
+ if (method.getCode() == null) {
+ return;
+ }
+ DexCode code = method.getCode().asDexCode();
+ if (code.highestSortingString != null) {
+ if (mapping.getOffsetFor(code.highestSortingString) > Constants.MAX_NON_JUMBO_INDEX) {
+ converter.processJumboStrings(method, mapping.getFirstJumboString());
}
}
}
@@ -181,8 +181,7 @@
// At least one method needs a jumbo string.
IRConverter converter = new IRConverter(application, appInfo, options, false);
for (DexProgramClass clazz : classes) {
- rewriteCodeWithJumboStrings(converter, clazz.directMethods());
- rewriteCodeWithJumboStrings(converter, clazz.virtualMethods());
+ clazz.forEachMethod(method -> rewriteCodeWithJumboStrings(converter, method));
}
return this;
}
@@ -275,56 +274,53 @@
private void checkInterfaceMethods() {
for (DexProgramClass clazz : mapping.getClasses()) {
if (clazz.isInterface()) {
- checkInterfaceMethods(clazz.directMethods());
- checkInterfaceMethods(clazz.virtualMethods());
+ clazz.forEachMethod(this::checkInterfaceMethod);
}
}
}
- // Ensures interface methods comply with requirements imposed by Android runtime:
+ // Ensures interface method comply with requirements imposed by Android runtime:
// -- in pre-N Android versions interfaces may only have class
// initializer and public abstract methods.
// -- starting with N interfaces may also have public or private
// static methods, as well as public non-abstract (default)
// and private instance methods.
- private void checkInterfaceMethods(DexEncodedMethod[] methods) {
- for (DexEncodedMethod method : methods) {
- if (application.dexItemFactory.isClassConstructor(method.method)) {
- continue; // Class constructor is always OK.
- }
- if (method.accessFlags.isStatic()) {
- if (!options.canUseDefaultAndStaticInterfaceMethods()) {
- throw new CompilationError("Static interface methods are only supported "
- + "starting with Android N (--min-api " + Constants.ANDROID_N_API + "): "
- + method.method.toSourceString());
- }
-
- } else {
- if (method.accessFlags.isConstructor()) {
- throw new CompilationError(
- "Interface must not have constructors: " + method.method.toSourceString());
- }
- if (!method.accessFlags.isAbstract() && !method.accessFlags.isPrivate() &&
- !options.canUseDefaultAndStaticInterfaceMethods()) {
- throw new CompilationError("Default interface methods are only supported "
- + "starting with Android N (--min-api " + Constants.ANDROID_N_API + "): "
- + method.method.toSourceString());
- }
- }
-
- if (method.accessFlags.isPrivate()) {
- if (options.canUsePrivateInterfaceMethods()) {
- continue;
- }
- throw new CompilationError("Private interface methods are only supported "
+ private void checkInterfaceMethod(DexEncodedMethod method) {
+ if (application.dexItemFactory.isClassConstructor(method.method)) {
+ return; // Class constructor is always OK.
+ }
+ if (method.accessFlags.isStatic()) {
+ if (!options.canUseDefaultAndStaticInterfaceMethods()) {
+ throw new CompilationError("Static interface methods are only supported "
+ "starting with Android N (--min-api " + Constants.ANDROID_N_API + "): "
+ method.method.toSourceString());
}
- if (!method.accessFlags.isPublic()) {
- throw new CompilationError("Interface methods must not be "
- + "protected or package private: " + method.method.toSourceString());
+ } else {
+ if (method.accessFlags.isConstructor()) {
+ throw new CompilationError(
+ "Interface must not have constructors: " + method.method.toSourceString());
}
+ if (!method.accessFlags.isAbstract() && !method.accessFlags.isPrivate() &&
+ !options.canUseDefaultAndStaticInterfaceMethods()) {
+ throw new CompilationError("Default interface methods are only supported "
+ + "starting with Android N (--min-api " + Constants.ANDROID_N_API + "): "
+ + method.method.toSourceString());
+ }
+ }
+
+ if (method.accessFlags.isPrivate()) {
+ if (options.canUsePrivateInterfaceMethods()) {
+ return;
+ }
+ throw new CompilationError("Private interface methods are only supported "
+ + "starting with Android N (--min-api " + Constants.ANDROID_N_API + "): "
+ + method.method.toSourceString());
+ }
+
+ if (!method.accessFlags.isPublic()) {
+ throw new CompilationError("Interface methods must not be "
+ + "protected or package private: " + method.method.toSourceString());
}
}
@@ -332,34 +328,30 @@
DexApplication application) {
Map<DexCode, String> codeToSignatureMap = new IdentityHashMap<>();
for (DexProgramClass clazz : mapping.getClasses()) {
- addSignaturesFromMethods(clazz.directMethods(), codeToSignatureMap,
- application.getProguardMap());
- addSignaturesFromMethods(clazz.virtualMethods(), codeToSignatureMap,
- application.getProguardMap());
+ clazz.forEachMethod(method ->
+ addSignaturesFromMethod(method, codeToSignatureMap, application.getProguardMap()));
}
DexCode[] codesArray = codes.toArray(new DexCode[codes.size()]);
Arrays.sort(codesArray, Comparator.comparing(codeToSignatureMap::get));
return Arrays.asList(codesArray);
}
- private static void addSignaturesFromMethods(DexEncodedMethod[] methods,
+ private static void addSignaturesFromMethod(DexEncodedMethod method,
Map<DexCode, String> codeToSignatureMap,
ClassNameMapper proguardMap) {
- for (DexEncodedMethod method : methods) {
- if (method.getCode() == null) {
- assert method.accessFlags.isAbstract() || method.accessFlags.isNative();
+ if (method.getCode() == null) {
+ assert method.accessFlags.isAbstract() || method.accessFlags.isNative();
+ } else {
+ Signature signature;
+ String originalClassName;
+ if (proguardMap != null) {
+ signature = proguardMap.originalSignatureOf(method.method);
+ originalClassName = proguardMap.originalNameOf(method.method.holder);
} else {
- Signature signature;
- String originalClassName;
- if (proguardMap != null) {
- signature = proguardMap.originalSignatureOf(method.method);
- originalClassName = proguardMap.originalNameOf(method.method.holder);
- } else {
- signature = MethodSignature.fromDexMethod(method.method);
- originalClassName = method.method.holder.toSourceString();
- }
- codeToSignatureMap.put(method.getCode().asDexCode(), originalClassName + signature);
+ signature = MethodSignature.fromDexMethod(method.method);
+ originalClassName = method.method.holder.toSourceString();
}
+ codeToSignatureMap.put(method.getCode().asDexCode(), originalClassName + signature);
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfo.java b/src/main/java/com/android/tools/r8/graph/AppInfo.java
index a5c8ff8..3619b9c 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -42,21 +42,12 @@
Builder<Descriptor, KeyedDexItem> builder = ImmutableMap.builder();
DexClass clazz = app.definitionFor(type);
if (clazz != null) {
- registerDefinitions(builder, clazz.directMethods());
- registerDefinitions(builder, clazz.virtualMethods());
- registerDefinitions(builder, clazz.instanceFields());
- registerDefinitions(builder, clazz.staticFields());
+ clazz.forEachMethod(method -> builder.put(method.getKey(), method));
+ clazz.forEachField(field -> builder.put(field.getKey(), field));
}
return builder.build();
}
- private void registerDefinitions(Builder<Descriptor, KeyedDexItem> builder,
- KeyedDexItem<? extends Descriptor>[] items) {
- for (KeyedDexItem<? extends Descriptor> item : items) {
- builder.put(item.getKey(), item);
- }
- }
-
public Iterable<DexProgramClass> classes() {
return app.classes();
}
diff --git a/src/main/java/com/android/tools/r8/graph/ClassAndMemberPublicizer.java b/src/main/java/com/android/tools/r8/graph/ClassAndMemberPublicizer.java
index 9583e9c..6a6b3d8 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassAndMemberPublicizer.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassAndMemberPublicizer.java
@@ -12,8 +12,8 @@
public static DexApplication run(DexApplication application) {
for (DexClass clazz : application.classes()) {
clazz.accessFlags.promoteToPublic();
- clazz.forEachMethod( method -> method.accessFlags.promoteNonPrivateToPublic());
- clazz.forEachField( field -> field.accessFlags.promoteToPublic());
+ clazz.forEachMethod(method -> method.accessFlags.promoteNonPrivateToPublic());
+ clazz.forEachField(field -> field.accessFlags.promoteToPublic());
}
return application;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexApplication.java b/src/main/java/com/android/tools/r8/graph/DexApplication.java
index d84dd8c..e57cd05 100644
--- a/src/main/java/com/android/tools/r8/graph/DexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DexApplication.java
@@ -193,16 +193,11 @@
*/
public void disassemble(Path outputDir, InternalOptions options) {
for (DexProgramClass clazz : programClasses.getAllClasses()) {
- for (DexEncodedMethod method : clazz.virtualMethods()) {
+ clazz.forEachMethod(method -> {
if (options.methodMatchesFilter(method)) {
disassemble(method, getProguardMap(), outputDir);
}
- }
- for (DexEncodedMethod method : clazz.directMethods()) {
- if (options.methodMatchesFilter(method)) {
- disassemble(method, getProguardMap(), outputDir);
- }
- }
+ });
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index b28f06c..a029a61 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -11,6 +11,7 @@
import com.google.common.base.MoreObjects;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.function.Consumer;
public abstract class DexClass extends DexItem {
@@ -168,10 +169,6 @@
return false;
}
- public DexClasspathClass asClasspathClass() {
- return null;
- }
-
public boolean isLibraryClass() {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
index 036b8bc..27ab302 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
@@ -41,11 +41,6 @@
}
@Override
- public DexClasspathClass asClasspathClass() {
- return this;
- }
-
- @Override
public DexClasspathClass get() {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
index 9c76d74..8b348a0 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
@@ -186,7 +186,7 @@
private static boolean allMethodsExists(DexApplication application, CallGraph graph) {
for (DexProgramClass clazz : application.classes()) {
- clazz.forEachMethod( method -> { assert graph.nodes.get(method) != null; });
+ clazz.forEachMethod(method -> { assert graph.nodes.get(method) != null; });
}
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index a345ddf..51aa284 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -6,6 +6,8 @@
import static com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.Flavor.ExcludeDexResources;
import static com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.Flavor.IncludeAllResources;
+import com.google.common.collect.ImmutableSet;
+
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
@@ -38,7 +40,6 @@
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
-import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -229,25 +230,19 @@
ExecutorService executor) throws ExecutionException {
List<Future<?>> futures = new ArrayList<>();
for (DexProgramClass clazz : classes) {
- futures.add(executor.submit(() -> {
- convertMethodsToDex(clazz.directMethods());
- convertMethodsToDex(clazz.virtualMethods());
- }));
+ futures.add(executor.submit(() -> clazz.forEachMethod(this::convertMethodToDex)));
}
ThreadUtils.awaitFutures(futures);
}
- private void convertMethodsToDex(DexEncodedMethod[] methods) {
- for (int i = 0; i < methods.length; i++) {
- DexEncodedMethod method = methods[i];
- if (method.getCode() != null) {
- boolean matchesMethodFilter = options.methodMatchesFilter(method);
- if (matchesMethodFilter) {
- if (method.getCode().isJarCode()) {
- rewriteCode(method, ignoreOptimizationFeedback, Outliner::noProcessing);
- }
- updateHighestSortingStrings(method);
+ private void convertMethodToDex(DexEncodedMethod method) {
+ if (method.getCode() != null) {
+ boolean matchesMethodFilter = options.methodMatchesFilter(method);
+ if (matchesMethodFilter) {
+ if (method.getCode().isJarCode()) {
+ rewriteCode(method, ignoreOptimizationFeedback, Outliner::noProcessing);
}
+ updateHighestSortingStrings(method);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
index d7b17c6..ec7fa46 100644
--- a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
@@ -3,6 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.Sets;
+
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -13,8 +16,7 @@
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.Timing;
-import com.google.common.base.Equivalence.Wrapper;
-import com.google.common.collect.Sets;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -337,19 +339,16 @@
: parent.createChild());
if (holder != null) {
boolean keepAll = holder.isLibraryClass() || holder.accessFlags.isAnnotation();
- reserveNamesForMethods(holder.virtualMethods(), keepAll, state);
- reserveNamesForMethods(holder.directMethods(), keepAll, state);
+ holder.forEachMethod(method -> reserveNamesForMethod(method, keepAll, state));
}
return state;
}
- private void reserveNamesForMethods(DexEncodedMethod[] methods,
+ private void reserveNamesForMethod(DexEncodedMethod method,
boolean keepAll, NamingState<DexProto> state) {
- for (DexEncodedMethod method : methods) {
- if (keepAll || rootSet.noObfuscation.contains(method)) {
- state.reserveName(method.method.name, method.method.proto);
- globalState.reserveName(method.method.name, method.method.proto);
- }
+ if (keepAll || rootSet.noObfuscation.contains(method)) {
+ state.reserveName(method.method.name, method.method.proto);
+ globalState.reserveName(method.method.name, method.method.proto);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/BridgeMethodAnalysis.java b/src/main/java/com/android/tools/r8/optimize/BridgeMethodAnalysis.java
index f36e8c5..1a28332 100644
--- a/src/main/java/com/android/tools/r8/optimize/BridgeMethodAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/BridgeMethodAnalysis.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.optimize.InvokeSingleTargetExtractor.InvokeKind;
+
import java.util.IdentityHashMap;
import java.util.Map;
@@ -28,35 +29,32 @@
public GraphLense run() {
for (DexClass clazz : appInfo.classes()) {
- identifyBridgeMethods(clazz.virtualMethods());
- identifyBridgeMethods(clazz.directMethods());
+ clazz.forEachMethod(this::identifyBridgeMethod);
}
return new BridgeLense(lense, bridgeTargetToBridgeMap);
}
- private void identifyBridgeMethods(DexEncodedMethod[] dexEncodedMethods) {
- for (DexEncodedMethod method : dexEncodedMethods) {
- if (method.accessFlags.isBridge()) {
- InvokeSingleTargetExtractor targetExtractor = new InvokeSingleTargetExtractor();
- method.getCode().registerReachableDefinitions(targetExtractor);
- DexMethod target = targetExtractor.getTarget();
- InvokeKind kind = targetExtractor.getKind();
- if (target != null &&
- target.proto.parameters.values.length == method.method.proto.parameters.values.length) {
- assert !method.accessFlags.isPrivate() && !method.accessFlags.isConstructor();
- target = lense.lookupMethod(target, method);
- if (kind == InvokeKind.STATIC) {
- assert method.accessFlags.isStatic();
- DexEncodedMethod targetMethod = appInfo.lookupStaticTarget(target);
- if (targetMethod != null) {
- addForwarding(method, targetMethod);
- }
- } else if (kind == InvokeKind.VIRTUAL) {
- // TODO(herhut): Add support for bridges with multiple targets.
- DexEncodedMethod targetMethod = appInfo.lookupSingleVirtualTarget(target);
- if (targetMethod != null) {
- addForwarding(method, targetMethod);
- }
+ private void identifyBridgeMethod(DexEncodedMethod method) {
+ if (method.accessFlags.isBridge()) {
+ InvokeSingleTargetExtractor targetExtractor = new InvokeSingleTargetExtractor();
+ method.getCode().registerReachableDefinitions(targetExtractor);
+ DexMethod target = targetExtractor.getTarget();
+ InvokeKind kind = targetExtractor.getKind();
+ if (target != null &&
+ target.proto.parameters.values.length == method.method.proto.parameters.values.length) {
+ assert !method.accessFlags.isPrivate() && !method.accessFlags.isConstructor();
+ target = lense.lookupMethod(target, method);
+ if (kind == InvokeKind.STATIC) {
+ assert method.accessFlags.isStatic();
+ DexEncodedMethod targetMethod = appInfo.lookupStaticTarget(target);
+ if (targetMethod != null) {
+ addForwarding(method, targetMethod);
+ }
+ } else if (kind == InvokeKind.VIRTUAL) {
+ // TODO(herhut): Add support for bridges with multiple targets.
+ DexEncodedMethod targetMethod = appInfo.lookupSingleVirtualTarget(target);
+ if (targetMethod != null) {
+ addForwarding(method, targetMethod);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/DebugStripper.java b/src/main/java/com/android/tools/r8/optimize/DebugStripper.java
index 3f83606..0eda1e5 100644
--- a/src/main/java/com/android/tools/r8/optimize/DebugStripper.java
+++ b/src/main/java/com/android/tools/r8/optimize/DebugStripper.java
@@ -17,8 +17,10 @@
import com.android.tools.r8.naming.MemberNaming.Range;
import com.android.tools.r8.naming.MemberNaming.Signature;
import com.android.tools.r8.utils.InternalOptions;
+
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
+
import java.util.List;
public class DebugStripper {
@@ -162,16 +164,6 @@
processCode(method, naming, nameCounts);
}
- private void processMethods(DexEncodedMethod[] methods, ClassNaming naming,
- Reference2IntMap<DexString> nameCounts) {
- if (methods == null) {
- return;
- }
- for (DexEncodedMethod method : methods) {
- processMethod(method, naming, nameCounts);
- }
- }
-
public void processClass(DexProgramClass clazz) {
if (!clazz.hasMethodsOrFields()) {
return;
@@ -179,20 +171,16 @@
String name = descriptorToName(clazz.type.toDescriptorString());
ClassNaming naming = classNameMapper == null ? null : classNameMapper.getClassNaming(name);
Reference2IntMap<DexString> nameCounts = new Reference2IntOpenHashMap<>();
- setIntialNameCounts(nameCounts, clazz.directMethods());
- setIntialNameCounts(nameCounts, clazz.virtualMethods());
- processMethods(clazz.directMethods(), naming, nameCounts);
- processMethods(clazz.virtualMethods(), naming, nameCounts);
+ clazz.forEachMethod(method -> setIntialNameCounts(nameCounts, method));
+ clazz.forEachMethod(method -> processMethod(method, naming, nameCounts));
}
private void setIntialNameCounts(Reference2IntMap<DexString> nameCounts,
- DexEncodedMethod[] methods) {
- for (DexEncodedMethod method : methods) {
- if (nameCounts.containsKey(method.method.name)) {
- nameCounts.put(method.method.name, USED_MORE_THAN_ONCE);
- } else {
- nameCounts.put(method.method.name, USED_ONCE);
- }
+ DexEncodedMethod method) {
+ if (nameCounts.containsKey(method.method.name)) {
+ nameCounts.put(method.method.name, USED_MORE_THAN_ONCE);
+ } else {
+ nameCounts.put(method.method.name, USED_ONCE);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/VisibilityBridgeRemover.java b/src/main/java/com/android/tools/r8/optimize/VisibilityBridgeRemover.java
index 6c3e715..31c7f1f 100644
--- a/src/main/java/com/android/tools/r8/optimize/VisibilityBridgeRemover.java
+++ b/src/main/java/com/android/tools/r8/optimize/VisibilityBridgeRemover.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.optimize;
+import com.google.common.collect.Sets;
+
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
@@ -11,7 +13,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.optimize.InvokeSingleTargetExtractor.InvokeKind;
-import com.google.common.collect.Sets;
+
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -27,27 +29,25 @@
this.application = application;
}
- private void identifyBridgeMethods(DexEncodedMethod[] dexEncodedMethods) {
- for (DexEncodedMethod method : dexEncodedMethods) {
- if (method.accessFlags.isBridge()) {
- InvokeSingleTargetExtractor targetExtractor = new InvokeSingleTargetExtractor();
- method.getCode().registerReachableDefinitions(targetExtractor);
- DexMethod target = targetExtractor.getTarget();
- InvokeKind kind = targetExtractor.getKind();
- if (target != null &&
- target.proto == method.method.proto) {
- assert !method.accessFlags.isPrivate() && !method.accessFlags.isConstructor();
- if (kind == InvokeKind.SUPER) {
- // This is a visibility forward, so check for the direct target.
- DexEncodedMethod targetMethod
- = appInfo.lookupVirtualDefinition(target.getHolder(), target);
- if (targetMethod != null && targetMethod.accessFlags.isPublic()) {
- if (Log.ENABLED) {
- Log.info(getClass(), "Removing visibility forwarding %s -> %s", method.method,
- targetMethod.method);
- }
- unneededVisibilityBridges.add(method);
+ private void identifyBridgeMethod(DexEncodedMethod method) {
+ if (method.accessFlags.isBridge()) {
+ InvokeSingleTargetExtractor targetExtractor = new InvokeSingleTargetExtractor();
+ method.getCode().registerReachableDefinitions(targetExtractor);
+ DexMethod target = targetExtractor.getTarget();
+ InvokeKind kind = targetExtractor.getKind();
+ if (target != null &&
+ target.proto == method.method.proto) {
+ assert !method.accessFlags.isPrivate() && !method.accessFlags.isConstructor();
+ if (kind == InvokeKind.SUPER) {
+ // This is a visibility forward, so check for the direct target.
+ DexEncodedMethod targetMethod
+ = appInfo.lookupVirtualDefinition(target.getHolder(), target);
+ if (targetMethod != null && targetMethod.accessFlags.isPublic()) {
+ if (Log.ENABLED) {
+ Log.info(getClass(), "Removing visibility forwarding %s -> %s", method.method,
+ targetMethod.method);
}
+ unneededVisibilityBridges.add(method);
}
}
}
@@ -76,8 +76,7 @@
public DexApplication run() {
for (DexClass clazz : appInfo.classes()) {
- identifyBridgeMethods(clazz.virtualMethods());
- identifyBridgeMethods(clazz.directMethods());
+ clazz.forEachMethod(this::identifyBridgeMethod);
}
if (!unneededVisibilityBridges.isEmpty()) {
removeUnneededVisibilityBridges();
diff --git a/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java b/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
index 8a7ee43..f6ac140 100644
--- a/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
@@ -150,8 +150,8 @@
addMainDexType(type);
// Super and interfaces are live, no need to add them.
traceAnnotationsDirectDendencies(clazz.annotations);
- clazz.forEachField( field -> addMainDexType(field.field.type));
- clazz.forEachMethod( method -> {
+ clazz.forEachField(field -> addMainDexType(field.field.type));
+ clazz.forEachMethod(method -> {
traceMethodDirectDependencies(method.method);
method.registerReachableDefinitions(codeDirectReferenceCollector);
});
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
index 8afe151..6ac5694 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -3,6 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
+import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.Sets;
+
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
@@ -21,8 +24,7 @@
import com.android.tools.r8.shaking.ProguardTypeMatcher.MatchSpecificType;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.ThreadUtils;
-import com.google.common.base.Equivalence.Wrapper;
-import com.google.common.collect.Sets;
+
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
@@ -246,8 +248,8 @@
DexType onlyIfClassKept) {
Set<Wrapper<DexMethod>> methodsMarked = new HashSet<>();
while (clazz != null) {
- markMethods(clazz.directMethods(), memberKeepRules, rule, methodsMarked, onlyIfClassKept);
- markMethods(clazz.virtualMethods(), memberKeepRules, rule, methodsMarked, onlyIfClassKept);
+ clazz.forEachMethod(method ->
+ markMethod(method, memberKeepRules, rule, methodsMarked, onlyIfClassKept));
clazz = application.definitionFor(clazz.superType);
}
}
@@ -255,8 +257,7 @@
private void markMatchingFields(DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules, ProguardConfigurationRule rule,
DexType onlyIfClassKept) {
- markFields(clazz.staticFields(), memberKeepRules, rule, onlyIfClassKept);
- markFields(clazz.instanceFields(), memberKeepRules, rule, onlyIfClassKept);
+ clazz.forEachField(field -> markField(field, memberKeepRules, rule, onlyIfClassKept));
}
public static void writeSeeds(Iterable<DexItem> seeds, PrintStream out) {
@@ -371,36 +372,32 @@
return typeCache.computeIfAbsent(type, DexType::toSourceString);
}
- private void markMethods(DexEncodedMethod[] methods, Collection<ProguardMemberRule> rules,
+ private void markMethod(DexEncodedMethod method, Collection<ProguardMemberRule> rules,
ProguardConfigurationRule context, Set<Wrapper<DexMethod>> methodsMarked,
DexType onlyIfClassKept) {
- for (DexEncodedMethod method : methods) {
- if (methodsMarked.contains(MethodSignatureEquivalence.get().wrap(method.method))) {
- continue;
- }
- for (ProguardMemberRule rule : rules) {
- if (rule.matches(method, this)) {
- if (Log.ENABLED) {
- Log.verbose(getClass(), "Marking method `%s` due to `%s { %s }`.", method, context,
- rule);
- }
- addItemToSets(method, context, rule, onlyIfClassKept);
+ if (methodsMarked.contains(MethodSignatureEquivalence.get().wrap(method.method))) {
+ return;
+ }
+ for (ProguardMemberRule rule : rules) {
+ if (rule.matches(method, this)) {
+ if (Log.ENABLED) {
+ Log.verbose(getClass(), "Marking method `%s` due to `%s { %s }`.", method, context,
+ rule);
}
+ addItemToSets(method, context, rule, onlyIfClassKept);
}
}
}
- private void markFields(DexEncodedField[] fields, Collection<ProguardMemberRule> rules,
+ private void markField(DexEncodedField field, Collection<ProguardMemberRule> rules,
ProguardConfigurationRule context, DexType onlyIfClassKept) {
- for (DexEncodedField field : fields) {
- for (ProguardMemberRule rule : rules) {
- if (rule.matches(field, this)) {
- if (Log.ENABLED) {
- Log.verbose(getClass(), "Marking field `%s` due to `%s { %s }`.", field, context,
- rule);
- }
- addItemToSets(field, context, rule, onlyIfClassKept);
+ for (ProguardMemberRule rule : rules) {
+ if (rule.matches(field, this)) {
+ if (Log.ENABLED) {
+ Log.verbose(getClass(), "Marking field `%s` due to `%s { %s }`.", field, context,
+ rule);
}
+ addItemToSets(field, context, rule, onlyIfClassKept);
}
}
}