diff options
Diffstat (limited to 'src/main/java/com/android/tools/r8/graph')
9 files changed, 101 insertions, 57 deletions
diff --git a/src/main/java/com/android/tools/r8/graph/Code.java b/src/main/java/com/android/tools/r8/graph/Code.java index dca5e02e9..84d6d5da6 100644 --- a/src/main/java/com/android/tools/r8/graph/Code.java +++ b/src/main/java/com/android/tools/r8/graph/Code.java @@ -34,15 +34,15 @@ public abstract class Code extends CanonicalizedDexItem { } public DexCode asDexCode() { - throw new Unreachable(); + throw new Unreachable(getClass().getCanonicalName() + ".asDexCode()"); } public JarCode asJarCode() { - throw new Unreachable(); + throw new Unreachable(getClass().getCanonicalName() + ".asJarCode()"); } public OutlineCode asOutlineCode() { - throw new Unreachable(); + throw new Unreachable(getClass().getCanonicalName() + ".asOutlineCode()"); } @Override diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java index 55aa9868a..1afd77ea3 100644 --- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java +++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java @@ -16,19 +16,6 @@ import java.util.ArrayList; import java.util.List; public class DexAnnotation extends DexItem { - // Dex system annotations. - // See https://source.android.com/devices/tech/dalvik/dex-format.html#system-annotation - private static final String ANNOTATION_DEFAULT_DESCRIPTOR = - "Ldalvik/annotation/AnnotationDefault;"; - private static final String ENCLOSING_CLASS_DESCRIPTOR = "Ldalvik/annotation/EnclosingClass;"; - private static final String ENCLOSING_METHOD_DESCRIPTOR = "Ldalvik/annotation/EnclosingMethod;"; - private static final String INNER_CLASS_DESCRIPTOR = "Ldalvik/annotation/InnerClass;"; - private static final String MEMBER_CLASSES_DESCRIPTOR = "Ldalvik/annotation/MemberClasses;"; - private static final String METHOD_PARAMETERS_DESCRIPTOR = "Ldalvik/annotation/MethodParameters;"; - private static final String SIGNATURE_DESCRIPTOR = "Ldalvik/annotation/Signature;"; - private static final String SOURCE_DEBUG_EXTENSION = "Ldalvik/annotation/SourceDebugExtension;"; - private static final String THROWS_DESCRIPTOR = "Ldalvik/annotation/Throws;"; - public static final int VISIBILITY_BUILD = 0x00; public static final int VISIBILITY_RUNTIME = 0x01; public static final int VISIBILITY_SYSTEM = 0x02; @@ -74,37 +61,36 @@ public class DexAnnotation extends DexItem { public static DexAnnotation createEnclosingClassAnnotation(DexType enclosingClass, DexItemFactory factory) { - return createSystemValueAnnotation(ENCLOSING_CLASS_DESCRIPTOR, factory, + return createSystemValueAnnotation(factory.annotationEnclosingClass, factory, new DexValueType(enclosingClass)); } public static DexAnnotation createEnclosingMethodAnnotation(DexMethod enclosingMethod, DexItemFactory factory) { - return createSystemValueAnnotation(ENCLOSING_METHOD_DESCRIPTOR, factory, + return createSystemValueAnnotation(factory.annotationEnclosingMethod, factory, new DexValueMethod(enclosingMethod)); } - public static boolean isEnclosingClassAnnotation(DexAnnotation annotation) { - return annotation.annotation.type.toDescriptorString().equals(ENCLOSING_CLASS_DESCRIPTOR); - } - - public static boolean isEnclosingMethodAnnotation(DexAnnotation annotation) { - return annotation.annotation.type.toDescriptorString().equals(ENCLOSING_METHOD_DESCRIPTOR); + public static boolean isEnclosingClassAnnotation(DexAnnotation annotation, + DexItemFactory factory) { + return annotation.annotation.type == factory.annotationEnclosingClass; } - public static boolean isEnclosingAnnotation(DexAnnotation annotation) { - return isEnclosingClassAnnotation(annotation) || isEnclosingMethodAnnotation(annotation); + public static boolean isEnclosingMethodAnnotation(DexAnnotation annotation, + DexItemFactory factory) { + return annotation.annotation.type == factory.annotationEnclosingMethod; } - public static boolean isInnerClassesAnnotation(DexAnnotation annotation) { - return annotation.annotation.type.toDescriptorString().equals(MEMBER_CLASSES_DESCRIPTOR) - || annotation.annotation.type.toDescriptorString().equals(INNER_CLASS_DESCRIPTOR); + public static boolean isInnerClassesAnnotation(DexAnnotation annotation, + DexItemFactory factory) { + return annotation.annotation.type == factory.annotationMemberClasses + || annotation.annotation.type == factory.annotationInnerClass; } public static DexAnnotation createInnerClassAnnotation(String clazz, int access, DexItemFactory factory) { return new DexAnnotation(VISIBILITY_SYSTEM, - new DexEncodedAnnotation(factory.createType(INNER_CLASS_DESCRIPTOR), + new DexEncodedAnnotation(factory.annotationInnerClass, new DexAnnotationElement[]{ new DexAnnotationElement( factory.createString("accessFlags"), @@ -123,14 +109,14 @@ public class DexAnnotation extends DexItem { for (int i = 0; i < classes.size(); i++) { values[i] = new DexValueType(classes.get(i)); } - return createSystemValueAnnotation(MEMBER_CLASSES_DESCRIPTOR, factory, + return createSystemValueAnnotation(factory.annotationMemberClasses, factory, new DexValueArray(values)); } public static DexAnnotation createSourceDebugExtensionAnnotation(DexValue value, DexItemFactory factory) { return new DexAnnotation(VISIBILITY_SYSTEM, - new DexEncodedAnnotation(factory.createType(SOURCE_DEBUG_EXTENSION), + new DexEncodedAnnotation(factory.annotationSourceDebugExtension, new DexAnnotationElement[] { new DexAnnotationElement(factory.createString("value"), value) })); @@ -140,7 +126,7 @@ public class DexAnnotation extends DexItem { DexValue[] accessFlags, DexItemFactory factory) { assert names.length == accessFlags.length; return new DexAnnotation(VISIBILITY_SYSTEM, - new DexEncodedAnnotation(factory.createType(METHOD_PARAMETERS_DESCRIPTOR), + new DexEncodedAnnotation(factory.annotationMethodParameters, new DexAnnotationElement[]{ new DexAnnotationElement( factory.createString("names"), @@ -153,7 +139,7 @@ public class DexAnnotation extends DexItem { public static DexAnnotation createAnnotationDefaultAnnotation(DexType type, List<DexAnnotationElement> defaults, DexItemFactory factory) { - return createSystemValueAnnotation(ANNOTATION_DEFAULT_DESCRIPTOR, factory, + return createSystemValueAnnotation(factory.annotationDefault, factory, new DexValueAnnotation( new DexEncodedAnnotation(type, defaults.toArray(new DexAnnotationElement[defaults.size()]))) @@ -161,34 +147,38 @@ public class DexAnnotation extends DexItem { } public static DexAnnotation createSignatureAnnotation(String signature, DexItemFactory factory) { - return createSystemValueAnnotation(SIGNATURE_DESCRIPTOR, factory, + return createSystemValueAnnotation(factory.annotationSignature, factory, compressSignature(signature, factory)); } public static DexAnnotation createThrowsAnnotation(DexValue[] exceptions, DexItemFactory factory) { - return createSystemValueAnnotation(THROWS_DESCRIPTOR, factory, new DexValueArray(exceptions)); + return createSystemValueAnnotation(factory.annotationThrows, factory, + new DexValueArray(exceptions)); } - private static DexAnnotation createSystemValueAnnotation(String desc, DexItemFactory factory, + private static DexAnnotation createSystemValueAnnotation(DexType type, DexItemFactory factory, DexValue value) { return new DexAnnotation(VISIBILITY_SYSTEM, - new DexEncodedAnnotation(factory.createType(desc), new DexAnnotationElement[] { + new DexEncodedAnnotation(type, new DexAnnotationElement[]{ new DexAnnotationElement(factory.createString("value"), value) })); } - public static boolean isThrowingAnnotation(DexAnnotation annotation) { - return annotation.annotation.type.toDescriptorString().equals(THROWS_DESCRIPTOR); + public static boolean isThrowingAnnotation(DexAnnotation annotation, + DexItemFactory factory) { + return annotation.annotation.type == factory.annotationThrows; } - public static boolean isSignatureAnnotation(DexAnnotation annotation) { - return annotation.annotation.type.toDescriptorString().equals(SIGNATURE_DESCRIPTOR); + public static boolean isSignatureAnnotation(DexAnnotation annotation, + DexItemFactory factory) { + return annotation.annotation.type == factory.annotationSignature; } - public static boolean isSourceDebugExtension(DexAnnotation annotation) { - return annotation.annotation.type.toDescriptorString().equals(SOURCE_DEBUG_EXTENSION); + public static boolean isSourceDebugExtension(DexAnnotation annotation, + DexItemFactory factory) { + return annotation.annotation.type == factory.annotationSourceDebugExtension; } /** diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java b/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java index 04e94d7ea..e91e1f009 100644 --- a/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java +++ b/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java @@ -68,6 +68,15 @@ public class DexAnnotationSet extends DexItem { sorted = hashCode(); } + public DexAnnotation getFirstMatching(DexType type) { + for (DexAnnotation annotation : annotations) { + if (annotation.annotation.type == type) { + return annotation; + } + } + return null; + } + private int sortedHashCode() { int hashCode = hashCode(); return hashCode == UNSORTED ? 1 : hashCode; 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 ca702fe3a..d84dd8c76 100644 --- a/src/main/java/com/android/tools/r8/graph/DexApplication.java +++ b/src/main/java/com/android/tools/r8/graph/DexApplication.java @@ -25,7 +25,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; -import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; @@ -87,7 +86,8 @@ public class DexApplication { } public List<DexProgramClass> classes() { - List<DexProgramClass> classes = programClasses.collectLoadedClasses(); + programClasses.forceLoad(type -> true); + List<DexProgramClass> classes = programClasses.getAllClasses(); assert reorderClasses(classes); return classes; } @@ -110,16 +110,16 @@ public class DexApplication { // program classes are supposed to be loaded, but force-loading them is no-op. programClasses.forceLoad(type -> true); - programClasses.collectLoadedClasses().forEach(clazz -> loaded.put(clazz.type, clazz)); + programClasses.getAllClasses().forEach(clazz -> loaded.put(clazz.type, clazz)); if (classpathClasses != null) { classpathClasses.forceLoad(type -> !loaded.containsKey(type)); - classpathClasses.collectLoadedClasses().forEach(clazz -> loaded.put(clazz.type, clazz)); + classpathClasses.getAllClasses().forEach(clazz -> loaded.putIfAbsent(clazz.type, clazz)); } if (libraryClasses != null) { libraryClasses.forceLoad(type -> !loaded.containsKey(type)); - libraryClasses.collectLoadedClasses().forEach(clazz -> loaded.put(clazz.type, clazz)); + libraryClasses.getAllClasses().forEach(clazz -> loaded.putIfAbsent(clazz.type, clazz)); } return loaded; @@ -192,7 +192,7 @@ public class DexApplication { * <p>If no directory is provided everything is written to System.out. */ public void disassemble(Path outputDir, InternalOptions options) { - for (DexProgramClass clazz : programClasses.collectLoadedClasses()) { + for (DexProgramClass clazz : programClasses.getAllClasses()) { for (DexEncodedMethod method : clazz.virtualMethods()) { if (options.methodMatchesFilter(method)) { disassemble(method, getProguardMap(), outputDir); @@ -246,7 +246,7 @@ public class DexApplication { * Write smali source for the application code on the provided PrintStream. */ public void smali(InternalOptions options, PrintStream ps) { - List<DexProgramClass> classes = programClasses.collectLoadedClasses(); + List<DexProgramClass> classes = programClasses.getAllClasses(); classes.sort(Comparator.comparing(DexProgramClass::toSourceString)); boolean firstClass = true; for (DexClass clazz : classes) { @@ -322,7 +322,7 @@ public class DexApplication { } public Builder(DexApplication application) { - programClasses = application.programClasses.collectLoadedClasses(); + programClasses = application.programClasses.getAllClasses(); classpathClasses = application.classpathClasses; libraryClasses = application.libraryClasses; proguardMap = application.proguardMap; 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 023cfb0e4..5b1b0f3f8 100644 --- a/src/main/java/com/android/tools/r8/graph/DexClass.java +++ b/src/main/java/com/android/tools/r8/graph/DexClass.java @@ -10,6 +10,7 @@ import com.android.tools.r8.errors.Unreachable; import com.google.common.base.MoreObjects; +import java.util.Arrays; import java.util.function.Consumer; public abstract class DexClass extends DexItem { @@ -83,6 +84,17 @@ public abstract class DexClass extends DexItem { } } + public DexEncodedMethod[] allMethodsSorted() { + int vLen = virtualMethods().length; + int dLen = directMethods().length; + DexEncodedMethod[] result = new DexEncodedMethod[vLen+dLen]; + System.arraycopy(virtualMethods(), 0, result, 0, vLen); + System.arraycopy(directMethods(), 0, result, vLen, dLen); + Arrays.sort(result, + (DexEncodedMethod a, DexEncodedMethod b) -> a.method.slowCompareTo(b.method)); + return result; + } + public DexEncodedField[] staticFields() { return MoreObjects.firstNonNull(staticFields, NO_FIELDS); } 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 dd5efbbd0..036b8bc74 100644 --- a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java +++ b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java @@ -7,8 +7,9 @@ import com.android.tools.r8.Resource; import com.android.tools.r8.dex.IndexedItemCollection; import com.android.tools.r8.dex.MixedSectionCollection; import com.android.tools.r8.errors.Unreachable; +import java.util.function.Supplier; -public class DexClasspathClass extends DexClass { +public class DexClasspathClass extends DexClass implements Supplier<DexClasspathClass> { public DexClasspathClass(DexType type, Resource.Kind origin, DexAccessFlags accessFlags, DexType superType, DexTypeList interfaces, DexString sourceFile, DexAnnotationSet annotations, @@ -43,4 +44,9 @@ public class DexClasspathClass extends DexClass { public DexClasspathClass asClasspathClass() { return this; } + + @Override + public DexClasspathClass get() { + return this; + } } diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java index 5dff4b432..36d732d8d 100644 --- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java +++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java @@ -129,8 +129,8 @@ public class DexItemFactory { public DexType annotationType = createType(annotationDescriptor); public DexType throwableType = createType(throwableDescriptor); - public DexType stringBuilderType = createType(createString("Ljava/lang/StringBuilder;")); - public DexType stringBufferType = createType(createString("Ljava/lang/StringBuffer;")); + public DexType stringBuilderType = createType("Ljava/lang/StringBuilder;"); + public DexType stringBufferType = createType("Ljava/lang/StringBuffer;"); public StringBuildingMethods stringBuilderMethods = new StringBuildingMethods(stringBuilderType); public StringBuildingMethods stringBufferMethods = new StringBuildingMethods(stringBufferType); @@ -140,6 +140,21 @@ public class DexItemFactory { public ThrowableMethods throwableMethods = new ThrowableMethods(); public ClassMethods classMethods = new ClassMethods(); + // Dex system annotations. + // See https://source.android.com/devices/tech/dalvik/dex-format.html#system-annotation + public final DexType annotationDefault = createType("Ldalvik/annotation/AnnotationDefault;"); + public final DexType annotationEnclosingClass = createType("Ldalvik/annotation/EnclosingClass;"); + public final DexType annotationEnclosingMethod = createType( + "Ldalvik/annotation/EnclosingMethod;"); + public final DexType annotationInnerClass = createType("Ldalvik/annotation/InnerClass;"); + public final DexType annotationMemberClasses = createType("Ldalvik/annotation/MemberClasses;"); + public final DexType annotationMethodParameters = createType( + "Ldalvik/annotation/MethodParameters;"); + public final DexType annotationSignature = createType("Ldalvik/annotation/Signature;"); + public final DexType annotationSourceDebugExtension = createType( + "Ldalvik/annotation/SourceDebugExtension;"); + public final DexType annotationThrows = createType("Ldalvik/annotation/Throws;"); + public void clearSubtypeInformation() { types.values().forEach(DexType::clearSubtypeInformation); } diff --git a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java index c1b9205e1..0c8ce8cf5 100644 --- a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java +++ b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java @@ -7,8 +7,9 @@ import com.android.tools.r8.Resource; import com.android.tools.r8.dex.IndexedItemCollection; import com.android.tools.r8.dex.MixedSectionCollection; import com.android.tools.r8.errors.Unreachable; +import java.util.function.Supplier; -public class DexLibraryClass extends DexClass { +public class DexLibraryClass extends DexClass implements Supplier<DexLibraryClass> { public DexLibraryClass(DexType type, Resource.Kind origin, DexAccessFlags accessFlags, DexType superType, DexTypeList interfaces, DexString sourceFile, DexAnnotationSet annotations, @@ -48,4 +49,9 @@ public class DexLibraryClass extends DexClass { public DexLibraryClass asLibraryClass() { return this; } + + @Override + public DexLibraryClass get() { + 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 f93a7da59..a38c9cb99 100644 --- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java +++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java @@ -7,8 +7,9 @@ import com.android.tools.r8.Resource; import com.android.tools.r8.dex.IndexedItemCollection; import com.android.tools.r8.dex.MixedSectionCollection; import java.util.Arrays; +import java.util.function.Supplier; -public class DexProgramClass extends DexClass { +public class DexProgramClass extends DexClass implements Supplier<DexProgramClass> { private DexEncodedArray staticValues; @@ -152,4 +153,9 @@ public class DexProgramClass extends DexClass { directMethods = Arrays.copyOf(directMethods, directMethods.length + 1); directMethods[directMethods.length - 1] = staticMethod; } + + @Override + public DexProgramClass get() { + return this; + } } |