Revert "Don't read DEX code from archives in any R8 compilation."
This reverts commit 893e91c0deb098a1c8db518e49ca980bbd8c9c1b.
Reason for revert: Breaks MainDexListTests
Change-Id: Ib1c78ec159d69ef48e4e3ad1d0e654ddfa2a3324
diff --git a/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java b/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
index 80f679b..b638235 100644
--- a/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
+++ b/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
@@ -15,6 +15,7 @@
boolean forceProguardCompatibility, DiagnosticsHandler diagnosticsHandler) {
super(diagnosticsHandler);
setProguardCompatibility(forceProguardCompatibility);
+ setIgnoreDexInArchive(true);
}
public CompatProguardCommandBuilder(boolean forceProguardCompatibility) {
@@ -25,5 +26,6 @@
boolean forceProguardCompatibility, boolean disableVerticalClassMerging) {
setProguardCompatibility(forceProguardCompatibility);
setDisableVerticalClassMerging(disableVerticalClassMerging);
+ setIgnoreDexInArchive(true);
}
}
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 1496f40..7923102 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -127,17 +127,14 @@
Builder(DiagnosticsHandler diagnosticsHandler) {
super(diagnosticsHandler);
- setIgnoreDexInArchive(true);
}
private Builder(AndroidApp app) {
super(app);
- setIgnoreDexInArchive(true);
}
private Builder(AndroidApp app, DiagnosticsHandler diagnosticsHandler) {
super(app, diagnosticsHandler);
- setIgnoreDexInArchive(true);
}
// Internal
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
index f375004..013a15b 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -22,7 +22,6 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ThrowableConsumer;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.references.Reference;
@@ -61,15 +60,16 @@
private static final String EXAMPLE_SRC_DIR = ToolHelper.EXAMPLES_DIR;
private static final String EXAMPLE_O_SRC_DIR = ToolHelper.EXAMPLES_ANDROID_O_DIR;
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withNoneRuntime().build();
+ @Parameters(name = "{0}, {1}")
+ public static List<Object[]> data() {
+ return buildParameters(getTestParameters().withNoneRuntime().build(), Backend.values());
}
- private final Backend backend = Backend.CF;
+ private final Backend backend;
- public MainDexTracingTest(TestParameters parameters) {
+ public MainDexTracingTest(TestParameters parameters, Backend backend) {
parameters.assertNoneRuntime();
+ this.backend = backend;
}
private Path getInputJar(Path cfJar) throws Exception {
diff --git a/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java b/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java
new file mode 100644
index 0000000..67e965d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java
@@ -0,0 +1,176 @@
+// Copyright (c) 2017, 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.smali;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.graph.DexCode;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class RemoveWriteOfUnusedFieldsTest extends SmaliTestBase {
+
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withDexRuntimes().build();
+ }
+
+ public RemoveWriteOfUnusedFieldsTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void unreadStaticFieldsRemoved() throws Exception {
+ SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
+
+ // All these static fields are set but never read.
+ builder.addStaticField("booleanField", "Z");
+ builder.addStaticField("byteField", "B");
+ builder.addStaticField("shortField", "S");
+ builder.addStaticField("intField", "I");
+ builder.addStaticField("longField", "J");
+ builder.addStaticField("floatField", "F");
+ builder.addStaticField("doubleField", "D");
+ builder.addStaticField("charField", "C");
+ builder.addStaticField("objectField", "Ljava/lang/Object;");
+ builder.addStaticField("stringField", "Ljava/lang/String;");
+ builder.addStaticField("testField", "LTest;");
+
+ builder.addStaticMethod("void", "test", ImmutableList.of(),
+ 2,
+ "const v0, 0", // single non-float typed zero (ie, int type)
+ "sput-boolean v0, LTest;->booleanField:Z",
+ "sput-byte v0, LTest;->byteField:B",
+ "sput-char v0, LTest;->charField:C",
+ "sput-short v0, LTest;->shortField:S",
+ "sput v0, LTest;->intField:I",
+ "const v0, 0", // float typed zero
+ "sput v0, LTest;->floatField:F",
+ "const v0, 0", // reference typed null
+ "sput-object v0, LTest;->objectField:Ljava/lang/Object;",
+ "sput-object v0, LTest;->stringField:Ljava/lang/String;",
+ "sput-object v0, LTest;->testField:LTest;",
+ "const-wide v0, 0", // wide typed long
+ "sput-wide v0, LTest;->longField:J",
+ "const-wide v0, 0", // wide typed double
+ "sput-wide v0, LTest;->doubleField:D",
+ "return-void");
+
+ builder.addMainMethod(
+ 0,
+ " invoke-static { }, LTest;->test()V",
+ " return-void ");
+
+ AndroidApp input =
+ AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build();
+
+ Path inputPath = temp.getRoot().toPath().resolve("input.zip");
+ input.writeToZip(inputPath, OutputMode.DexIndexed);
+ ToolHelper.runArtNoVerificationErrors(inputPath.toString(), DEFAULT_CLASS_NAME);
+
+ testForR8(parameters.getBackend())
+ .addProgramFiles(inputPath)
+ .addKeepMainRule("Test")
+ .setMinApi(parameters.getRuntime())
+ .compile()
+ .inspect(
+ inspector -> {
+ MethodSubject method =
+ inspector.clazz("Test").method("void", "test", ImmutableList.of());
+ assertThat(
+ "Expected method to be removed entirely because it does not have side effects",
+ method,
+ not(isPresent()));
+ });
+ }
+
+ @Test
+ public void unreadInstanceFieldsRemoved() throws Exception {
+ SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
+
+ // All these instance fields are set but never read.
+ builder.addInstanceField("booleanField", "Z");
+ builder.addInstanceField("byteField", "B");
+ builder.addInstanceField("shortField", "S");
+ builder.addInstanceField("intField", "I");
+ builder.addInstanceField("longField", "J");
+ builder.addInstanceField("floatField", "F");
+ builder.addInstanceField("doubleField", "D");
+ builder.addInstanceField("charField", "C");
+ builder.addInstanceField("objectField", "Ljava/lang/Object;");
+ builder.addInstanceField("stringField", "Ljava/lang/String;");
+ builder.addInstanceField("testField", "LTest;");
+
+ builder.addInstanceMethod("void", "test", ImmutableList.of(),
+ 2,
+ "const v0, 0",
+ "iput-boolean v0, p0, LTest;->booleanField:Z",
+ "iput-byte v0, p0, LTest;->byteField:B",
+ "iput-char v0, p0, LTest;->charField:C",
+ "iput-short v0, p0, LTest;->shortField:S",
+ "iput v0, p0, LTest;->intField:I",
+ "const v0, 0",
+ "iput v0, p0, LTest;->floatField:F",
+ "const v0, 0",
+ "iput-object v0, p0, LTest;->objectField:Ljava/lang/Object;",
+ "iput-object v0, p0, LTest;->stringField:Ljava/lang/String;",
+ "iput-object v0, p0, LTest;->testField:LTest;",
+ "const-wide v0, 0",
+ "iput-wide v0, p0, LTest;->longField:J",
+ "const-wide v0, 0",
+ "iput-wide v0, p0, LTest;->doubleField:D",
+ "return-void");
+
+ builder.addInitializer(ImmutableList.of(), 0,
+ "invoke-direct {p0}, Ljava/lang/Object;-><init>()V",
+ "return-void"
+ );
+
+ builder.addMainMethod(
+ 1,
+ " new-instance v0, LTest;",
+ " invoke-direct { v0 }, LTest;-><init>()V",
+ " invoke-virtual { v0 }, LTest;->test()V",
+ " return-void ");
+
+ AndroidApp input =
+ AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build();
+
+ Path inputPath = temp.getRoot().toPath().resolve("input.zip");
+ input.writeToZip(inputPath, OutputMode.DexIndexed);
+ ToolHelper.runArtNoVerificationErrors(inputPath.toString(), DEFAULT_CLASS_NAME);
+
+ testForR8(parameters.getBackend())
+ .addProgramFiles(inputPath)
+ .addKeepMainRule("Test")
+ .addKeepRules("-keep class Test { void test(); }")
+ .setMinApi(parameters.getRuntime())
+ .compile()
+ .inspect(
+ inspector -> {
+ MethodSubject method =
+ inspector.clazz("Test").method("void", "test", ImmutableList.of());
+ DexCode code = method.getMethod().getCode().asDexCode();
+ assertTrue(code.isEmptyVoidMethod());
+ });
+ }
+}