Merge "Build keep rules for the Proguard compatiblity actions"
diff --git a/src/main/java/com/android/tools/r8/cf/CfConstants.java b/src/main/java/com/android/tools/r8/cf/CfConstants.java
deleted file mode 100644
index 06a2562..0000000
--- a/src/main/java/com/android/tools/r8/cf/CfConstants.java
+++ /dev/null
@@ -1,220 +0,0 @@
-// 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.cf;
-
-import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
-import org.objectweb.asm.Opcodes;
-
-public abstract class CfConstants {
-
- private static final Int2ReferenceMap<String> OPCODE_NAMES;
- static {
- OPCODE_NAMES = new Int2ReferenceArrayMap<>(Opcodes.IFNONNULL + 1);
- OPCODE_NAMES.put(0, "nop");
- OPCODE_NAMES.put(1, "aconst_null");
- OPCODE_NAMES.put(2, "iconst_m1");
- OPCODE_NAMES.put(3, "iconst_0");
- OPCODE_NAMES.put(4, "iconst_1");
- OPCODE_NAMES.put(5, "iconst_2");
- OPCODE_NAMES.put(6, "iconst_3");
- OPCODE_NAMES.put(7, "iconst_4");
- OPCODE_NAMES.put(8, "iconst_5");
- OPCODE_NAMES.put(9, "lconst_0");
- OPCODE_NAMES.put(10, "lconst_1");
- OPCODE_NAMES.put(11, "fconst_0");
- OPCODE_NAMES.put(12, "fconst_1");
- OPCODE_NAMES.put(13, "fconst_2");
- OPCODE_NAMES.put(14, "dconst_0");
- OPCODE_NAMES.put(15, "dconst_1");
- OPCODE_NAMES.put(16, "bipush");
- OPCODE_NAMES.put(17, "sipush");
- OPCODE_NAMES.put(18, "ldc");
- // LDC_W = 19;
- // LDC2_W = 20;
- OPCODE_NAMES.put(21, "iload");
- OPCODE_NAMES.put(22, "lload");
- OPCODE_NAMES.put(23, "fload");
- OPCODE_NAMES.put(24, "dload");
- OPCODE_NAMES.put(25, "aload");
- // ILOAD_0 = 26;
- // ILOAD_1 = 27;
- // ILOAD_2 = 28;
- // ILOAD_3 = 29;
- // LLOAD_0 = 30;
- // LLOAD_1 = 31;
- // LLOAD_2 = 32;
- // LLOAD_3 = 33;
- // FLOAD_0 = 34;
- // FLOAD_1 = 35;
- // FLOAD_2 = 36;
- // FLOAD_3 = 37;
- // DLOAD_0 = 38;
- // DLOAD_1 = 39;
- // DLOAD_2 = 40;
- // DLOAD_3 = 41;
- // ALOAD_0 = 42;
- // ALOAD_1 = 43;
- // ALOAD_2 = 44;
- // ALOAD_3 = 45;
- OPCODE_NAMES.put(46, "iaload");
- OPCODE_NAMES.put(47, "laload");
- OPCODE_NAMES.put(48, "faload");
- OPCODE_NAMES.put(49, "daload");
- OPCODE_NAMES.put(50, "aaload");
- OPCODE_NAMES.put(51, "baload");
- OPCODE_NAMES.put(52, "caload");
- OPCODE_NAMES.put(53, "saload");
- OPCODE_NAMES.put(54, "istore");
- OPCODE_NAMES.put(55, "lstore");
- OPCODE_NAMES.put(56, "fstore");
- OPCODE_NAMES.put(57, "dstore");
- OPCODE_NAMES.put(58, "astore");
- // ISTORE_0 = 59;
- // ISTORE_1 = 60;
- // ISTORE_2 = 61;
- // ISTORE_3 = 62;
- // LSTORE_0 = 63;
- // LSTORE_1 = 64;
- // LSTORE_2 = 65;
- // LSTORE_3 = 66;
- // FSTORE_0 = 67;
- // FSTORE_1 = 68;
- // FSTORE_2 = 69;
- // FSTORE_3 = 70;
- // DSTORE_0 = 71;
- // DSTORE_1 = 72;
- // DSTORE_2 = 73;
- // DSTORE_3 = 74;
- // ASTORE_0 = 75;
- // ASTORE_1 = 76;
- // ASTORE_2 = 77;
- // ASTORE_3 = 78;
- OPCODE_NAMES.put(79, "iastore");
- OPCODE_NAMES.put(80, "lastore");
- OPCODE_NAMES.put(81, "fastore");
- OPCODE_NAMES.put(82, "dastore");
- OPCODE_NAMES.put(83, "aastore");
- OPCODE_NAMES.put(84, "bastore");
- OPCODE_NAMES.put(85, "castore");
- OPCODE_NAMES.put(86, "sastore");
- OPCODE_NAMES.put(87, "pop");
- OPCODE_NAMES.put(88, "pop2");
- OPCODE_NAMES.put(89, "dup");
- OPCODE_NAMES.put(90, "dup_x1");
- OPCODE_NAMES.put(91, "dup_x2");
- OPCODE_NAMES.put(92, "dup2");
- OPCODE_NAMES.put(93, "dup2_x1");
- OPCODE_NAMES.put(94, "dup2_x2");
- OPCODE_NAMES.put(95, "swap");
- OPCODE_NAMES.put(96, "iadd");
- OPCODE_NAMES.put(97, "ladd");
- OPCODE_NAMES.put(98, "fadd");
- OPCODE_NAMES.put(99, "dadd");
- OPCODE_NAMES.put(100, "isub");
- OPCODE_NAMES.put(101, "lsub");
- OPCODE_NAMES.put(102, "fsub");
- OPCODE_NAMES.put(103, "dsub");
- OPCODE_NAMES.put(104, "imul");
- OPCODE_NAMES.put(105, "lmul");
- OPCODE_NAMES.put(106, "fmul");
- OPCODE_NAMES.put(107, "dmul");
- OPCODE_NAMES.put(108, "idiv");
- OPCODE_NAMES.put(109, "ldiv");
- OPCODE_NAMES.put(110, "fdiv");
- OPCODE_NAMES.put(111, "ddiv");
- OPCODE_NAMES.put(112, "irem");
- OPCODE_NAMES.put(113, "lrem");
- OPCODE_NAMES.put(114, "frem");
- OPCODE_NAMES.put(115, "drem");
- OPCODE_NAMES.put(116, "ineg");
- OPCODE_NAMES.put(117, "lneg");
- OPCODE_NAMES.put(118, "fneg");
- OPCODE_NAMES.put(119, "dneg");
- OPCODE_NAMES.put(120, "ishl");
- OPCODE_NAMES.put(121, "lshl");
- OPCODE_NAMES.put(122, "ishr");
- OPCODE_NAMES.put(123, "lshr");
- OPCODE_NAMES.put(124, "iushr");
- OPCODE_NAMES.put(125, "lushr");
- OPCODE_NAMES.put(126, "iand");
- OPCODE_NAMES.put(127, "land");
- OPCODE_NAMES.put(128, "ior");
- OPCODE_NAMES.put(129, "lor");
- OPCODE_NAMES.put(130, "ixor");
- OPCODE_NAMES.put(131, "lxor");
- OPCODE_NAMES.put(132, "iinc");
- OPCODE_NAMES.put(133, "i2l");
- OPCODE_NAMES.put(134, "i2f");
- OPCODE_NAMES.put(135, "i2d");
- OPCODE_NAMES.put(136, "l2i");
- OPCODE_NAMES.put(137, "l2f");
- OPCODE_NAMES.put(138, "l2d");
- OPCODE_NAMES.put(139, "f2i");
- OPCODE_NAMES.put(140, "f2l");
- OPCODE_NAMES.put(141, "f2d");
- OPCODE_NAMES.put(142, "d2i");
- OPCODE_NAMES.put(143, "d2l");
- OPCODE_NAMES.put(144, "d2f");
- OPCODE_NAMES.put(145, "i2b");
- OPCODE_NAMES.put(146, "i2c");
- OPCODE_NAMES.put(147, "i2s");
- OPCODE_NAMES.put(148, "lcmp");
- OPCODE_NAMES.put(149, "fcmpl");
- OPCODE_NAMES.put(150, "fcmpg");
- OPCODE_NAMES.put(151, "dcmpl");
- OPCODE_NAMES.put(152, "dcmpg");
- OPCODE_NAMES.put(153, "ifeq");
- OPCODE_NAMES.put(154, "ifne");
- OPCODE_NAMES.put(155, "iflt");
- OPCODE_NAMES.put(156, "ifge");
- OPCODE_NAMES.put(157, "ifgt");
- OPCODE_NAMES.put(158, "ifle");
- OPCODE_NAMES.put(159, "if_icmpeq");
- OPCODE_NAMES.put(160, "if_icmpne");
- OPCODE_NAMES.put(161, "if_icmplt");
- OPCODE_NAMES.put(162, "if_icmpge");
- OPCODE_NAMES.put(163, "if_icmpgt");
- OPCODE_NAMES.put(164, "if_icmple");
- OPCODE_NAMES.put(165, "if_acmpeq");
- OPCODE_NAMES.put(166, "if_acmpne");
- OPCODE_NAMES.put(167, "goto");
- OPCODE_NAMES.put(168, "jsr");
- OPCODE_NAMES.put(169, "ret");
- OPCODE_NAMES.put(170, "tableswitch");
- OPCODE_NAMES.put(171, "lookupswitch");
- OPCODE_NAMES.put(172, "ireturn");
- OPCODE_NAMES.put(173, "lreturn");
- OPCODE_NAMES.put(174, "freturn");
- OPCODE_NAMES.put(175, "dreturn");
- OPCODE_NAMES.put(176, "areturn");
- OPCODE_NAMES.put(177, "return");
- OPCODE_NAMES.put(178, "getstatic");
- OPCODE_NAMES.put(179, "putstatic");
- OPCODE_NAMES.put(180, "getfield");
- OPCODE_NAMES.put(181, "putfield");
- OPCODE_NAMES.put(182, "invokevirtual");
- OPCODE_NAMES.put(183, "invokespecial");
- OPCODE_NAMES.put(184, "invokestatic");
- OPCODE_NAMES.put(185, "invokeinterface");
- OPCODE_NAMES.put(186, "invokedynamic");
- OPCODE_NAMES.put(187, "new");
- OPCODE_NAMES.put(188, "newarray");
- OPCODE_NAMES.put(189, "anewarray");
- OPCODE_NAMES.put(190, "arraylength");
- OPCODE_NAMES.put(191, "athrow");
- OPCODE_NAMES.put(192, "checkcast");
- OPCODE_NAMES.put(193, "instanceof");
- OPCODE_NAMES.put(194, "monitorenter");
- OPCODE_NAMES.put(195, "monitorexit");
- // WIDE = 196
- OPCODE_NAMES.put(197, "multianewarray");
- OPCODE_NAMES.put(198, "ifnull");
- OPCODE_NAMES.put(199, "ifnonnull");
- }
-
- public static String opcodeName(int opcode) {
- return OPCODE_NAMES.get(opcode);
- }
-}
diff --git a/src/main/java/com/android/tools/r8/cf/CfPrinter.java b/src/main/java/com/android/tools/r8/cf/CfPrinter.java
index da6b2f3..32f2f9f 100644
--- a/src/main/java/com/android/tools/r8/cf/CfPrinter.java
+++ b/src/main/java/com/android/tools/r8/cf/CfPrinter.java
@@ -39,6 +39,7 @@
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.Type;
+import org.objectweb.asm.util.Printer;
/**
* Utility to print CF code and instructions.
@@ -121,11 +122,11 @@
}
public void print(CfBinop binop) {
- print(CfConstants.opcodeName(binop.getOpcode()));
+ print(opcodeName(binop.getOpcode()));
}
public void print(CfUnop unop) {
- print(CfConstants.opcodeName(unop.getOpcode()));
+ print(opcodeName(unop.getOpcode()));
}
public void print(CfPop pop) {
@@ -149,7 +150,7 @@
public void print(CfInvoke invoke) {
indent();
- builder.append(invoke.getOpcode()).append(' ');
+ builder.append(opcodeName(invoke.getOpcode())).append(' ');
appendMethod(invoke.getMethod());
}
@@ -336,6 +337,10 @@
builder.append(method.proto.toDescriptorString());
}
+ private String opcodeName(int opcode) {
+ return Printer.OPCODES[opcode].toLowerCase();
+ }
+
@Override
public String toString() {
return builder.toString();
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstString.java b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
index febbda3..412a7a1 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstString.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.utils.InternalOptions;
+import java.io.UTFDataFormatException;
public class ConstString extends ConstInstruction {
@@ -86,8 +87,21 @@
@Override
public boolean canBeDeadCode(IRCode code, InternalOptions options) {
- // The const-string instruction is a throwing instruction in DEX, but not so in CF.
- return options.outputClassFiles;
+ // The const-string instruction can be a throwing instruction in DEX, if decode() fails,
+ // but not so in CF.
+ if (options.outputClassFiles) {
+ return true;
+ }
+ try {
+ value.toString();
+ } catch (RuntimeException e) {
+ if (e.getCause() instanceof UTFDataFormatException) {
+ return false;
+ } else {
+ throw e;
+ }
+ }
+ return true;
}
@Override
diff --git a/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java b/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
index 2c7927e..8480791 100644
--- a/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
+++ b/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
@@ -53,15 +53,11 @@
assertTrue(method.isPresent());
DexCode code = method.getMethod().getCode().asDexCode();
- // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
assertTrue(code.instructions[0] instanceof ConstString);
ConstString constString = (ConstString) code.instructions[0];
- assertEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[1] instanceof ConstString);
- constString = (ConstString) code.instructions[1];
assertNotEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[2] instanceof InvokeStatic);
- assertTrue(code.instructions[3] instanceof ReturnVoid);
+ assertTrue(code.instructions[1] instanceof InvokeStatic);
+ assertTrue(code.instructions[2] instanceof ReturnVoid);
}
@Test
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
index fa7a608..62c1bec 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
@@ -62,14 +62,10 @@
DexCode code = method.getCode().asDexCode();
assertTrue(code.instructions[0] instanceof InvokeDirect);
assertTrue(code.instructions[1] instanceof ConstString);
- // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
ConstString constString = (ConstString) code.instructions[1];
assertEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[2] instanceof ConstString);
- constString = (ConstString) code.instructions[2];
- assertEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[3] instanceof IputObject);
- assertTrue(code.instructions[4] instanceof ReturnVoid);
+ assertTrue(code.instructions[2] instanceof IputObject);
+ assertTrue(code.instructions[3] instanceof ReturnVoid);
}
@Test
@@ -169,15 +165,11 @@
assertNotNull(method);
DexCode code = method.getCode().asDexCode();
- // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
assertTrue(code.instructions[0] instanceof ConstString);
ConstString constString = (ConstString) code.instructions[0];
assertEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[1] instanceof ConstString);
- constString = (ConstString) code.instructions[1];
- assertEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[2] instanceof SputObject);
- assertTrue(code.instructions[3] instanceof ReturnVoid);
+ assertTrue(code.instructions[1] instanceof SputObject);
+ assertTrue(code.instructions[2] instanceof ReturnVoid);
}
@Test
@@ -375,18 +367,14 @@
DexCode code = method.getCode().asDexCode();
assertTrue(code.instructions[0] instanceof InvokeDirect);
- // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
assertTrue(code.instructions[1] instanceof ConstString);
ConstString constString = (ConstString) code.instructions[1];
- assertEquals(BOO, constString.getString().toString());
+ assertEquals("Mixed/form.Boo", constString.getString().toString());
assertTrue(code.instructions[2] instanceof ConstString);
constString = (ConstString) code.instructions[2];
- assertEquals("Mixed/form.Boo", constString.getString().toString());
- assertTrue(code.instructions[3] instanceof ConstString);
- constString = (ConstString) code.instructions[3];
assertEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[4] instanceof InvokeStatic);
- assertTrue(code.instructions[5] instanceof ReturnVoid);
+ assertTrue(code.instructions[3] instanceof InvokeStatic);
+ assertTrue(code.instructions[4] instanceof ReturnVoid);
}
@Test
@@ -516,15 +504,11 @@
DexCode code = method.getCode().asDexCode();
assertTrue(code.instructions[0] instanceof InvokeDirect);
assertTrue(code.instructions[1] instanceof ConstClass);
- // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
assertTrue(code.instructions[2] instanceof ConstString);
ConstString constString = (ConstString) code.instructions[2];
assertEquals("foo", constString.getString().toString());
- assertTrue(code.instructions[3] instanceof ConstString);
- constString = (ConstString) code.instructions[3];
- assertEquals("foo", constString.getString().toString());
- assertTrue(code.instructions[4] instanceof InvokeStatic);
- assertTrue(code.instructions[5] instanceof ReturnVoid);
+ assertTrue(code.instructions[3] instanceof InvokeStatic);
+ assertTrue(code.instructions[4] instanceof ReturnVoid);
}
@Test
@@ -568,15 +552,11 @@
DexCode code = method.getCode().asDexCode();
assertTrue(code.instructions[0] instanceof InvokeDirect);
assertTrue(code.instructions[1] instanceof ConstClass);
- // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
assertTrue(code.instructions[2] instanceof ConstString);
ConstString constString = (ConstString) code.instructions[2];
- assertEquals("foo", constString.getString().toString());
- assertTrue(code.instructions[3] instanceof ConstString);
- constString = (ConstString) code.instructions[3];
assertNotEquals("foo", constString.getString().toString());
- assertTrue(code.instructions[4] instanceof InvokeStatic);
- assertTrue(code.instructions[5] instanceof ReturnVoid);
+ assertTrue(code.instructions[3] instanceof InvokeStatic);
+ assertTrue(code.instructions[4] instanceof ReturnVoid);
}
@Test
@@ -631,15 +611,11 @@
assertTrue(code.instructions[3] instanceof NewArray);
assertTrue(code.instructions[4] instanceof Const4);
assertTrue(code.instructions[5] instanceof AputObject);
- // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
assertTrue(code.instructions[6] instanceof ConstString);
ConstString constString = (ConstString) code.instructions[6];
assertEquals("foo", constString.getString().toString());
- assertTrue(code.instructions[7] instanceof ConstString);
- constString = (ConstString) code.instructions[7];
- assertEquals("foo", constString.getString().toString());
- assertTrue(code.instructions[8] instanceof InvokeStatic);
- assertTrue(code.instructions[9] instanceof ReturnVoid);
+ assertTrue(code.instructions[7] instanceof InvokeStatic);
+ assertTrue(code.instructions[8] instanceof ReturnVoid);
}
@Test
@@ -694,15 +670,11 @@
assertTrue(code.instructions[3] instanceof NewArray);
assertTrue(code.instructions[4] instanceof Const4);
assertTrue(code.instructions[5] instanceof AputObject);
- // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
assertTrue(code.instructions[6] instanceof ConstString);
ConstString constString = (ConstString) code.instructions[6];
- assertEquals("foo", constString.getString().toString());
- assertTrue(code.instructions[7] instanceof ConstString);
- constString = (ConstString) code.instructions[7];
assertNotEquals("foo", constString.getString().toString());
- assertTrue(code.instructions[8] instanceof InvokeStatic);
- assertTrue(code.instructions[9] instanceof ReturnVoid);
+ assertTrue(code.instructions[7] instanceof InvokeStatic);
+ assertTrue(code.instructions[8] instanceof ReturnVoid);
}
private DexInspector getInspectorAfterRunR8(