Enable CF on IdentifierMinifierTest and related improvements:

(use the following breakdown for the review process)

1. Fix: ignore synthetic positions prior to any actual ones, for CF backend.
   Affected test: ExamplesDebugTest/testEnclosingmethod_proguarded

       file: - CfBuilder

2. Fix missing canonicalization in CfSourceCode.getDebugPositionAtOffset
   and rename it to getCanonicalDebugPositionAtOffset.
   Affected test IdentifierMinifierTest / test_getmembers.

       files: - CfSourceCode
              - (related renaming only:) IrBuilder, SourceCode, DexSourceCode,
                Outliner, JarSourceCode, SyntheticSourceCode, MainDexListTests

3. Extend IdentifierMinifier.adaptClassStringsInMethod() and
   replaceIdentifierNameStringInMethod() with CF support:

       file: - IdentifierMinifier

4. Add dedicated ConstInstructionSubject, fix missing '@Override's:

       files: - src/test/jcatr8/utils/dexinspector/*
              - (related minor changes:) NeverReturnsNormallyTest,
                MoveStringConstantsTest

5. Replace DEX-specific checks with generic '*Subject' checks in
   IdentifierMinifierTest and enable CF backend.

        file: - IdentifierMinifierTest

Change-Id: Ie43a28c4cf1cf715d970d8fcdf415e4a20312af4
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
index 54ae1c6..b2114b3 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
@@ -13,7 +13,7 @@
 
 public class CfConstString extends CfInstruction {
 
-  private final DexString string;
+  private DexString string;
 
   public CfConstString(DexString string) {
     this.string = string;
@@ -23,6 +23,10 @@
     return string;
   }
 
+  public void setString(DexString string) {
+    this.string = string;
+  }
+
   @Override
   public void write(MethodVisitor visitor, NamingLens lens) {
     visitor.visitLdcInsn(string.toString());
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index f276cb2..f5b0a31 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -385,6 +385,9 @@
     boolean didPositionChange =
         position.isSome()
             && position != currentPosition
+            // Ignore synthetic positions prior to any actual position, except when inlined
+            // (that is, callerPosition != null).
+            && !(currentPosition.isNone() && position.synthetic && position.callerPosition == null)
             && (options.debug || instruction.instructionTypeCanThrow());
     if (!didLocalsChange && !didPositionChange) {
       return;
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
index 92645c4..957a1f3 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
@@ -395,14 +395,8 @@
       if (instruction instanceof CfPosition) {
         CfPosition cfPosition = (CfPosition) instruction;
         Position position = cfPosition.getPosition();
-        Position newPosition =
-            canonicalPositions.getCanonical(
-                new Position(
-                    position.line,
-                    position.file,
-                    position.method,
-                    canonicalPositions.canonicalizeCallerPosition(position.callerPosition)));
-        CfPosition newCfPosition = new CfPosition(cfPosition.getLabel(), newPosition);
+        CfPosition newCfPosition =
+            new CfPosition(cfPosition.getLabel(), getCanonicalPosition(position));
         newCfPosition.buildIR(builder, state, this);
       } else {
         instruction.buildIR(builder, state, this);
@@ -441,7 +435,8 @@
     for (int i = 0; i < stack.length; i++) {
       stack[i] = convertUninitialized(frame.getStack().get(i));
     }
-    state.setStateFromFrame(locals, stack, getDebugPositionAtOffset(currentInstructionIndex));
+    state.setStateFromFrame(
+        locals, stack, getCanonicalDebugPositionAtOffset(currentInstructionIndex));
   }
 
   private DexType convertUninitialized(FrameType type) {
@@ -624,7 +619,7 @@
   }
 
   @Override
-  public Position getDebugPositionAtOffset(int offset) {
+  public Position getCanonicalDebugPositionAtOffset(int offset) {
     while (offset + 1 < code.getInstructions().size()) {
       CfInstruction insn = code.getInstructions().get(offset);
       if (!(insn instanceof CfLabel) && !(insn instanceof CfFrame)) {
@@ -636,13 +631,22 @@
       offset -= 1;
     }
     if (offset < 0) {
-      return Position.noneWithMethod(method.method, callerPosition);
+      return canonicalPositions.getPreamblePosition();
     }
-    return ((CfPosition) code.getInstructions().get(offset)).getPosition();
+    return getCanonicalPosition(((CfPosition) code.getInstructions().get(offset)).getPosition());
   }
 
   @Override
   public Position getCurrentPosition() {
     return state.getPosition();
   }
+
+  private Position getCanonicalPosition(Position position) {
+    return canonicalPositions.getCanonical(
+        new Position(
+            position.line,
+            position.file,
+            position.method,
+            canonicalPositions.canonicalizeCallerPosition(position.callerPosition)));
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
index 9a9b836..10bf6a5 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
@@ -184,7 +184,7 @@
   }
 
   @Override
-  public Position getDebugPositionAtOffset(int offset) {
+  public Position getCanonicalDebugPositionAtOffset(int offset) {
     DexDebugEntry entry = getDebugEntryAtOffset(offset);
     return entry == null
         ? canonicalPositions.getPreamblePosition()
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 963cf41..62450d4 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -592,7 +592,7 @@
     int moveExceptionDest = source.getMoveExceptionRegister(targetIndex);
     if (moveExceptionDest >= 0) {
       Value out = writeRegister(moveExceptionDest, ValueType.OBJECT, ThrowingInfo.NO_THROW, null);
-      Position position = source.getDebugPositionAtOffset(moveExceptionItem.targetOffset);
+      Position position = source.getCanonicalDebugPositionAtOffset(moveExceptionItem.targetOffset);
       MoveException moveException = new MoveException(out);
       moveException.setPosition(position);
       currentBlock.add(moveException);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
index 23d9a73..1170dab 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
@@ -493,7 +493,7 @@
       // Don't include line changes when processing a label. Doing so will end up emitting local
       // writes after the line has changed and thus causing locals to become visible too late.
       currentPosition =
-          getDebugPositionAtOffset(
+          getCanonicalDebugPositionAtOffset(
               ((instructionIndex > 0) && (insn instanceof LabelNode))
                   ? instructionIndex - 1
                   : instructionIndex);
@@ -2832,7 +2832,7 @@
   }
 
   @Override
-  public Position getDebugPositionAtOffset(int offset) {
+  public Position getCanonicalDebugPositionAtOffset(int offset) {
     if (offset == EXCEPTIONAL_SYNC_EXIT_OFFSET) {
       return getExceptionalExitPosition();
     }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/SourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/SourceCode.java
index bf2b51f..2bc2aa1 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/SourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/SourceCode.java
@@ -27,7 +27,7 @@
 
   Position getCurrentPosition();
 
-  Position getDebugPositionAtOffset(int offset);
+  Position getCanonicalDebugPositionAtOffset(int offset);
 
   /**
    * Trace block structure of the source-program.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index c3a3781..6f3a0f5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -1106,7 +1106,7 @@
     }
 
     @Override
-    public Position getDebugPositionAtOffset(int offset) {
+    public Position getCanonicalDebugPositionAtOffset(int offset) {
       throw new Unreachable();
     }
 
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
index c64d8ed..991d371 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
@@ -214,7 +214,7 @@
   }
 
   @Override
-  public Position getDebugPositionAtOffset(int offset) {
+  public Position getCanonicalDebugPositionAtOffset(int offset) {
     throw new Unreachable();
   }
 
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java b/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
index 2fd66d0..d92de6b 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
@@ -5,9 +5,12 @@
 
 import static com.android.tools.r8.utils.DescriptorUtils.descriptorToJavaType;
 
+import com.android.tools.r8.cf.code.CfConstString;
+import com.android.tools.r8.cf.code.CfInstruction;
 import com.android.tools.r8.code.ConstString;
 import com.android.tools.r8.code.ConstStringJumbo;
 import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.Code;
 import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.graph.DexEncodedField;
@@ -34,9 +37,7 @@
   private final Set<DexItem> identifierNameStrings;
 
   IdentifierMinifier(
-      AppInfoWithLiveness appInfo,
-      ProguardClassFilter adaptClassStrings,
-      NamingLens lens) {
+      AppInfoWithLiveness appInfo, ProguardClassFilter adaptClassStrings, NamingLens lens) {
     this.appInfo = appInfo;
     this.adaptClassStrings = adaptClassStrings;
     this.lens = lens;
@@ -86,17 +87,29 @@
     if (code == null) {
       return;
     }
-    assert code.isDexCode();
-    DexCode dexCode = code.asDexCode();
-    for (Instruction instr : dexCode.instructions) {
-      if (instr instanceof ConstString) {
-        ConstString cnst = (ConstString) instr;
-        DexString dexString = cnst.getString();
-        cnst.BBBB = getRenamedStringLiteral(dexString);
-      } else if (instr instanceof ConstStringJumbo) {
-        ConstStringJumbo cnst = (ConstStringJumbo) instr;
-        DexString dexString = cnst.getString();
-        cnst.BBBBBBBB = getRenamedStringLiteral(dexString);
+    if (code.isDexCode()) {
+      DexCode dexCode = code.asDexCode();
+      for (Instruction instr : dexCode.instructions) {
+        if (instr instanceof ConstString) {
+          ConstString cnst = (ConstString) instr;
+          DexString dexString = cnst.getString();
+          cnst.BBBB = getRenamedStringLiteral(dexString);
+        } else if (instr instanceof ConstStringJumbo) {
+          ConstStringJumbo cnst = (ConstStringJumbo) instr;
+          DexString dexString = cnst.getString();
+          cnst.BBBBBBBB = getRenamedStringLiteral(dexString);
+        }
+      }
+    } else {
+      assert code.isCfCode();
+      CfCode cfCode = code.asCfCode();
+
+      for (CfInstruction instr : cfCode.getInstructions()) {
+        if (instr instanceof CfConstString) {
+          CfConstString cnst = (CfConstString) instr;
+          DexString dexString = cnst.getString();
+          cnst.setString(getRenamedStringLiteral(dexString));
+        }
       }
     }
   }
@@ -153,19 +166,32 @@
     if (code == null) {
       return;
     }
-    assert code.isDexCode();
-    DexCode dexCode = code.asDexCode();
-    for (Instruction instr : dexCode.instructions) {
-      if (instr instanceof ConstString
-          && ((ConstString) instr).getString() instanceof DexItemBasedString) {
-        ConstString cnst = (ConstString) instr;
-        DexItemBasedString itemBasedString = (DexItemBasedString) cnst.getString();
-        cnst.BBBB = materialize(itemBasedString);
-      } else if (instr instanceof ConstStringJumbo
-          && ((ConstStringJumbo) instr).getString() instanceof DexItemBasedString) {
-        ConstStringJumbo cnst = (ConstStringJumbo) instr;
-        DexItemBasedString itemBasedString = (DexItemBasedString) cnst.getString();
-        cnst.BBBBBBBB = materialize(itemBasedString);
+    if (code.isDexCode()) {
+      DexCode dexCode = code.asDexCode();
+      for (Instruction instr : dexCode.instructions) {
+        if (instr instanceof ConstString
+            && ((ConstString) instr).getString() instanceof DexItemBasedString) {
+          ConstString cnst = (ConstString) instr;
+          DexItemBasedString itemBasedString = (DexItemBasedString) cnst.getString();
+          cnst.BBBB = materialize(itemBasedString);
+        } else if (instr instanceof ConstStringJumbo
+            && ((ConstStringJumbo) instr).getString() instanceof DexItemBasedString) {
+          ConstStringJumbo cnst = (ConstStringJumbo) instr;
+          DexItemBasedString itemBasedString = (DexItemBasedString) cnst.getString();
+          cnst.BBBBBBBB = materialize(itemBasedString);
+        }
+      }
+    } else {
+      assert code.isCfCode();
+      CfCode cfCode = code.asCfCode();
+
+      for (CfInstruction instr : cfCode.getInstructions()) {
+        if (instr instanceof CfConstString
+            && ((CfConstString) instr).getString() instanceof DexItemBasedString) {
+          CfConstString cnst = (CfConstString) instr;
+          DexItemBasedString itemBasedString = (DexItemBasedString) cnst.getString();
+          cnst.setString(materialize(itemBasedString));
+        }
       }
     }
   }
@@ -184,5 +210,4 @@
       return lens.lookupName((DexField) itemBasedString.basedOn);
     }
   }
-
 }
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index dc5347e..8e1692c 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -771,7 +771,7 @@
     }
 
     @Override
-    public Position getDebugPositionAtOffset(int offset) {
+    public Position getCanonicalDebugPositionAtOffset(int offset) {
       throw new Unreachable();
     }
 
diff --git a/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java b/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
index 9b120e6..60e9d08 100644
--- a/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
+++ b/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.utils.dexinspector.ClassSubject;
 import com.android.tools.r8.utils.dexinspector.DexInspector;
 import com.android.tools.r8.utils.dexinspector.InstructionSubject;
+import com.android.tools.r8.utils.dexinspector.InstructionSubject.JumboStringMode;
 import com.android.tools.r8.utils.dexinspector.MethodSubject;
 import com.google.common.collect.ImmutableList;
 import java.util.Iterator;
@@ -53,26 +54,26 @@
         clazz.method("void", "foo", ImmutableList.of(
             "java.lang.String", "java.lang.String", "java.lang.String", "java.lang.String"));
     assertTrue(methodThrowToBeInlined.isPresent());
-    validateSequence(methodThrowToBeInlined.iterateInstructions(),
+    validateSequence(
+        methodThrowToBeInlined.iterateInstructions(),
         // 'if' with "foo#1" is flipped.
         InstructionSubject::isIfEqz,
 
         // 'if' with "foo#2" is removed along with the constant.
 
         // 'if' with "foo#3" is removed so now we have unconditional call.
-        insn -> insn.isConstString("StringConstants::foo#3"),
+        insn -> insn.isConstString("StringConstants::foo#3", JumboStringMode.DISALLOW),
         InstructionSubject::isInvokeStatic,
         InstructionSubject::isThrow,
 
         // 'if's with "foo#4" and "foo#5" are flipped, but their throwing branches
         // are not moved to the end of the code (area for improvement?).
-        insn -> insn.isConstString("StringConstants::foo#4"),
+        insn -> insn.isConstString("StringConstants::foo#4", JumboStringMode.DISALLOW),
         InstructionSubject::isIfEqz, // Flipped if
         InstructionSubject::isGoto, // Jump around throwing branch.
         InstructionSubject::isInvokeStatic, // Throwing branch.
         InstructionSubject::isThrow,
-
-        insn -> insn.isConstString("StringConstants::foo#5"),
+        insn -> insn.isConstString("StringConstants::foo#5", JumboStringMode.DISALLOW),
         InstructionSubject::isIfEqz, // Flipped if
         InstructionSubject::isReturnVoid, // Final return statement.
         InstructionSubject::isInvokeStatic, // Throwing branch.
@@ -80,10 +81,9 @@
 
         // After 'if' with "foo#1" flipped, always throwing branch
         // moved here along with the constant.
-        insn -> insn.isConstString("StringConstants::foo#1"),
+        insn -> insn.isConstString("StringConstants::foo#1", JumboStringMode.DISALLOW),
         InstructionSubject::isInvokeStatic,
-        InstructionSubject::isThrow
-    );
+        InstructionSubject::isThrow);
   }
 
   @SafeVarargs
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierMinifierTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierMinifierTest.java
index 58e17d1..7ab6cf1 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierMinifierTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierMinifierTest.java
@@ -6,28 +6,29 @@
 import static com.android.tools.r8.utils.DescriptorUtils.descriptorToJavaType;
 import static com.android.tools.r8.utils.DescriptorUtils.isValidJavaType;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.R8Command;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.code.ConstString;
-import com.android.tools.r8.code.ConstStringJumbo;
-import com.android.tools.r8.code.Instruction;
-import com.android.tools.r8.graph.Code;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexValue.DexValueString;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.ListUtils;
 import com.android.tools.r8.utils.dexinspector.ClassSubject;
+import com.android.tools.r8.utils.dexinspector.ConstStringInstructionSubject;
 import com.android.tools.r8.utils.dexinspector.DexInspector;
+import com.android.tools.r8.utils.dexinspector.FoundMethodSubject;
+import com.android.tools.r8.utils.dexinspector.InstructionSubject;
+import com.android.tools.r8.utils.dexinspector.InstructionSubject.JumboStringMode;
 import com.android.tools.r8.utils.dexinspector.MethodSubject;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
+import com.google.common.collect.Streams;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
@@ -48,14 +49,19 @@
   private final String appFileName;
   private final List<String> keepRulesFiles;
   private final Consumer<DexInspector> inspection;
+  private final Backend backend;
 
   public IdentifierMinifierTest(
+      Backend backend,
       String test,
       List<String> keepRulesFiles,
       Consumer<DexInspector> inspection) {
-    this.appFileName = ToolHelper.EXAMPLES_BUILD_DIR + test + "/classes.dex";
+    assert backend == Backend.DEX || backend == Backend.CF;
+    this.appFileName =
+        ToolHelper.EXAMPLES_BUILD_DIR + test + (backend == Backend.DEX ? "/classes.dex" : ".jar");
     this.keepRulesFiles = keepRulesFiles;
     this.inspection = inspection;
+    this.backend = backend;
   }
 
   private AndroidApp processedApp;
@@ -65,25 +71,34 @@
     Path out = temp.getRoot().toPath();
     R8Command.Builder builder =
         ToolHelper.addProguardConfigurationConsumer(
-            R8Command.builder(),
-            pgConfig -> {
-              pgConfig.setPrintMapping(true);
-              pgConfig.setPrintMappingFile(out.resolve(ToolHelper.DEFAULT_PROGUARD_MAP_FILE));
-            })
-            .setOutput(out, OutputMode.DexIndexed)
-            .addProguardConfigurationFiles(ListUtils.map(keepRulesFiles, Paths::get))
-            .addLibraryFiles(ToolHelper.getDefaultAndroidJar());
+                R8Command.builder(),
+                pgConfig -> {
+                  pgConfig.setPrintMapping(true);
+                  pgConfig.setPrintMappingFile(out.resolve(ToolHelper.DEFAULT_PROGUARD_MAP_FILE));
+                })
+            .setOutput(out, backend == Backend.DEX ? OutputMode.DexIndexed : OutputMode.ClassFile)
+            .addProguardConfigurationFiles(ListUtils.map(keepRulesFiles, Paths::get));
+    if (backend == Backend.DEX) {
+      builder.addLibraryFiles(ToolHelper.getDefaultAndroidJar());
+    } else if (backend == Backend.CF) {
+      builder.addLibraryFiles(Paths.get(ToolHelper.JAVA_8_RUNTIME));
+    }
     ToolHelper.getAppBuilder(builder).addProgramFiles(Paths.get(appFileName));
     processedApp = ToolHelper.runR8(builder.build(), o -> o.debug = false);
   }
 
   @Test
   public void identiferMinifierTest() throws Exception {
-    DexInspector dexInspector = new DexInspector(processedApp);
+    DexInspector dexInspector =
+        new DexInspector(
+            processedApp,
+            options -> {
+              options.enableCfFrontend = true;
+            });
     inspection.accept(dexInspector);
   }
 
-  @Parameters(name = "test: {0} keep: {1}")
+  @Parameters(name = "[{0}] test: {1} keep: {2}")
   public static Collection<Object[]> data() {
     List<String> tests = Arrays.asList(
         "adaptclassstrings",
@@ -103,25 +118,38 @@
     inspections.put("identifiernamestring:keep-rules-2.txt", IdentifierMinifierTest::test2_rule2);
     inspections.put("identifiernamestring:keep-rules-3.txt", IdentifierMinifierTest::test2_rule3);
 
-    return NamingTestBase.createTests(tests, inspections);
+    Collection<Object[]> parameters = NamingTestBase.createTests(tests, inspections);
+
+    // Duplicate parameters for each backend.
+    List<Object[]> parametersWithBackend = new ArrayList<>();
+    for (Backend backend : Backend.values()) {
+      for (Object[] row : parameters) {
+        Object[] newRow = new Object[row.length + 1];
+        newRow[0] = backend;
+        System.arraycopy(row, 0, newRow, 1, row.length);
+        parametersWithBackend.add(newRow);
+      }
+    }
+
+    return parametersWithBackend;
   }
 
   // Without -adaptclassstrings
   private static void test1_rule1(DexInspector inspector) {
     ClassSubject mainClass = inspector.clazz("adaptclassstrings.Main");
     MethodSubject main = mainClass.method(DexInspector.MAIN);
-    Code mainCode = main.getMethod().getCode();
-    verifyPresenceOfConstString(mainCode.asDexCode().instructions);
-    int renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, mainCode.asDexCode().instructions);
+    assertTrue(main instanceof FoundMethodSubject);
+    FoundMethodSubject foundMain = (FoundMethodSubject) main;
+    verifyPresenceOfConstString(foundMain);
+    int renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundMain);
     assertEquals(0, renamedYetFoundIdentifierCount);
 
     ClassSubject aClass = inspector.clazz("adaptclassstrings.A");
     MethodSubject bar = aClass.method("void", "bar", ImmutableList.of());
-    Code barCode = bar.getMethod().getCode();
-    verifyPresenceOfConstString(barCode.asDexCode().instructions);
-    renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, barCode.asDexCode().instructions);
+    assertTrue(bar instanceof FoundMethodSubject);
+    FoundMethodSubject foundBar = (FoundMethodSubject) bar;
+    verifyPresenceOfConstString(foundBar);
+    renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundBar);
     assertEquals(0, renamedYetFoundIdentifierCount);
 
     renamedYetFoundIdentifierCount =
@@ -133,18 +161,18 @@
   private static void test1_rule2(DexInspector inspector) {
     ClassSubject mainClass = inspector.clazz("adaptclassstrings.Main");
     MethodSubject main = mainClass.method(DexInspector.MAIN);
-    Code mainCode = main.getMethod().getCode();
-    verifyPresenceOfConstString(mainCode.asDexCode().instructions);
-    int renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, mainCode.asDexCode().instructions);
+    assertTrue(main instanceof FoundMethodSubject);
+    FoundMethodSubject foundMain = (FoundMethodSubject) main;
+    verifyPresenceOfConstString(foundMain);
+    int renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundMain);
     assertEquals(0, renamedYetFoundIdentifierCount);
 
     ClassSubject aClass = inspector.clazz("adaptclassstrings.A");
     MethodSubject bar = aClass.method("void", "bar", ImmutableList.of());
-    Code barCode = bar.getMethod().getCode();
-    verifyPresenceOfConstString(barCode.asDexCode().instructions);
-    renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, barCode.asDexCode().instructions);
+    assertTrue(bar instanceof FoundMethodSubject);
+    FoundMethodSubject foundBar = (FoundMethodSubject) bar;
+    verifyPresenceOfConstString(foundBar);
+    renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundBar);
     assertEquals(1, renamedYetFoundIdentifierCount);
 
     renamedYetFoundIdentifierCount =
@@ -155,41 +183,43 @@
   private static void test_atomicfieldupdater(DexInspector inspector) {
     ClassSubject mainClass = inspector.clazz("atomicfieldupdater.Main");
     MethodSubject main = mainClass.method(DexInspector.MAIN);
-    Code mainCode = main.getMethod().getCode();
-    verifyPresenceOfConstString(mainCode.asDexCode().instructions);
+    assertTrue(main instanceof FoundMethodSubject);
+    FoundMethodSubject foundMain = (FoundMethodSubject) main;
+    verifyPresenceOfConstString(foundMain);
 
     ClassSubject a = inspector.clazz("atomicfieldupdater.A");
-    Set<Instruction> constStringInstructions =
-        getRenamedMemberIdentifierConstStrings(a, mainCode.asDexCode().instructions);
+    Set<InstructionSubject> constStringInstructions =
+        getRenamedMemberIdentifierConstStrings(a, foundMain);
     assertEquals(3, constStringInstructions.size());
   }
 
   private static void test_forname(DexInspector inspector) {
     ClassSubject mainClass = inspector.clazz("forname.Main");
     MethodSubject main = mainClass.method(DexInspector.MAIN);
-    Code mainCode = main.getMethod().getCode();
-    verifyPresenceOfConstString(mainCode.asDexCode().instructions);
-    int renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, mainCode.asDexCode().instructions);
+    assertTrue(main instanceof FoundMethodSubject);
+    FoundMethodSubject foundMain = (FoundMethodSubject) main;
+    verifyPresenceOfConstString(foundMain);
+    int renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundMain);
     assertEquals(1, renamedYetFoundIdentifierCount);
   }
 
   private static void test_getmembers(DexInspector inspector) {
     ClassSubject mainClass = inspector.clazz("getmembers.Main");
     MethodSubject main = mainClass.method(DexInspector.MAIN);
-    Code mainCode = main.getMethod().getCode();
-    verifyPresenceOfConstString(mainCode.asDexCode().instructions);
+    assertTrue(main instanceof FoundMethodSubject);
+    FoundMethodSubject foundMain = (FoundMethodSubject) main;
+    verifyPresenceOfConstString(foundMain);
 
     ClassSubject a = inspector.clazz("getmembers.A");
-    Set<Instruction> constStringInstructions =
-        getRenamedMemberIdentifierConstStrings(a, mainCode.asDexCode().instructions);
+    Set<InstructionSubject> constStringInstructions =
+        getRenamedMemberIdentifierConstStrings(a, foundMain);
     assertEquals(2, constStringInstructions.size());
 
     ClassSubject b = inspector.clazz("getmembers.B");
     MethodSubject inliner = b.method("java.lang.String", "inliner", ImmutableList.of());
-    Code inlinerCode = inliner.getMethod().getCode();
-    constStringInstructions =
-        getRenamedMemberIdentifierConstStrings(a, inlinerCode.asDexCode().instructions);
+    assertTrue(inliner instanceof FoundMethodSubject);
+    FoundMethodSubject foundInliner = (FoundMethodSubject) inliner;
+    constStringInstructions = getRenamedMemberIdentifierConstStrings(a, foundInliner);
     assertEquals(1, constStringInstructions.size());
   }
 
@@ -197,19 +227,19 @@
   private static void test2_rule1(DexInspector inspector) {
     ClassSubject mainClass = inspector.clazz("identifiernamestring.Main");
     MethodSubject main = mainClass.method(DexInspector.MAIN);
-    Code mainCode = main.getMethod().getCode();
-    verifyPresenceOfConstString(mainCode.asDexCode().instructions);
-    int renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, mainCode.asDexCode().instructions);
+    assertTrue(main instanceof FoundMethodSubject);
+    FoundMethodSubject foundMain = (FoundMethodSubject) main;
+    verifyPresenceOfConstString(foundMain);
+    int renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundMain);
     assertEquals(0, renamedYetFoundIdentifierCount);
 
     ClassSubject aClass = inspector.clazz("identifiernamestring.A");
     MethodSubject aInit =
         aClass.method("void", "<init>", ImmutableList.of());
-    Code initCode = aInit.getMethod().getCode();
-    verifyPresenceOfConstString(initCode.asDexCode().instructions);
-    renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, initCode.asDexCode().instructions);
+    assertTrue(aInit instanceof FoundMethodSubject);
+    FoundMethodSubject foundAInit = (FoundMethodSubject) aInit;
+    verifyPresenceOfConstString(foundAInit);
+    renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundAInit);
     assertEquals(0, renamedYetFoundIdentifierCount);
 
     renamedYetFoundIdentifierCount =
@@ -221,21 +251,19 @@
   private static void test2_rule2(DexInspector inspector) {
     ClassSubject mainClass = inspector.clazz("identifiernamestring.Main");
     MethodSubject main = mainClass.method(DexInspector.MAIN);
-    assertTrue(main.isPresent());
-    Code mainCode = main.getMethod().getCode();
-    assertTrue(mainCode.isDexCode());
-    verifyPresenceOfConstString(mainCode.asDexCode().instructions);
-    int renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, mainCode.asDexCode().instructions);
+    assertTrue(main instanceof FoundMethodSubject);
+    FoundMethodSubject foundMain = (FoundMethodSubject) main;
+    verifyPresenceOfConstString(foundMain);
+    int renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundMain);
     assertEquals(1, renamedYetFoundIdentifierCount);
 
     ClassSubject aClass = inspector.clazz("identifiernamestring.A");
     MethodSubject aInit =
         aClass.method("void", "<init>", ImmutableList.of());
-    Code initCode = aInit.getMethod().getCode();
-    verifyPresenceOfConstString(initCode.asDexCode().instructions);
-    renamedYetFoundIdentifierCount =
-        countRenamedClassIdentifier(inspector, initCode.asDexCode().instructions);
+    assertTrue(aInit instanceof FoundMethodSubject);
+    FoundMethodSubject foundAInit = (FoundMethodSubject) aInit;
+    verifyPresenceOfConstString(foundAInit);
+    renamedYetFoundIdentifierCount = countRenamedClassIdentifier(inspector, foundAInit);
     assertEquals(1, renamedYetFoundIdentifierCount);
 
     renamedYetFoundIdentifierCount =
@@ -247,55 +275,47 @@
   private static void test2_rule3(DexInspector inspector) {
     ClassSubject mainClass = inspector.clazz("identifiernamestring.Main");
     MethodSubject main = mainClass.method(DexInspector.MAIN);
-    assertTrue(main.isPresent());
-    Code mainCode = main.getMethod().getCode();
-    assertTrue(mainCode.isDexCode());
-    verifyPresenceOfConstString(mainCode.asDexCode().instructions);
+    assertTrue(main instanceof FoundMethodSubject);
+    FoundMethodSubject foundMain = (FoundMethodSubject) main;
+    verifyPresenceOfConstString(foundMain);
 
     ClassSubject b = inspector.clazz("identifiernamestring.B");
-    Set<Instruction> constStringInstructions =
-        getRenamedMemberIdentifierConstStrings(b, mainCode.asDexCode().instructions);
+    Set<InstructionSubject> constStringInstructions =
+        getRenamedMemberIdentifierConstStrings(b, foundMain);
     assertEquals(2, constStringInstructions.size());
   }
 
-  private static void verifyPresenceOfConstString(Instruction[] instructions) {
-    boolean presence =
-        Arrays.stream(instructions)
-            .anyMatch(instr -> instr instanceof ConstString || instr instanceof ConstStringJumbo);
-    assertTrue(presence);
+  private static void verifyPresenceOfConstString(FoundMethodSubject method) {
+    assertTrue(
+        method
+            .iterateInstructions(instruction -> instruction.isConstString(JumboStringMode.ALLOW))
+            .hasNext());
   }
 
-  private static String retrieveString(Instruction instr) {
-    if (instr instanceof ConstString) {
-      ConstString cnst = (ConstString) instr;
-      return cnst.getString().toString();
-    } else if (instr instanceof ConstStringJumbo) {
-      ConstStringJumbo cnst = (ConstStringJumbo) instr;
-      return cnst.getString().toString();
-    }
-    return null;
-  }
-
-  private static Stream<Instruction> getConstStringInstructions(Instruction[] instructions) {
-    return Arrays.stream(instructions)
-        .filter(instr -> instr instanceof ConstString || instr instanceof ConstStringJumbo);
+  private static Stream<InstructionSubject> getConstStringInstructions(FoundMethodSubject method) {
+    return Streams.stream(method.iterateInstructions())
+        .filter(instr -> instr.isConstString(JumboStringMode.ALLOW));
   }
 
   private static int countRenamedClassIdentifier(
-      DexInspector inspector, Instruction[] instructions) {
-    return getConstStringInstructions(instructions)
-        .reduce(0, (cnt, instr) -> {
-          String cnstString = retrieveString(instr);
-          assertNotNull(cnstString);
-          if (isValidJavaType(cnstString)) {
-            ClassSubject classSubject = inspector.clazz(cnstString);
-            if (classSubject.isRenamed()
-                && descriptorToJavaType(classSubject.getFinalDescriptor()).equals(cnstString)) {
-              return cnt + 1;
-            }
-          }
-          return cnt;
-        }, Integer::sum);
+      DexInspector inspector, FoundMethodSubject method) {
+    return getConstStringInstructions(method)
+        .reduce(
+            0,
+            (cnt, instr) -> {
+              assert (instr instanceof ConstStringInstructionSubject);
+              String cnstString =
+                  ((ConstStringInstructionSubject) instr).getString().toSourceString();
+              if (isValidJavaType(cnstString)) {
+                ClassSubject classSubject = inspector.clazz(cnstString);
+                if (classSubject.isRenamed()
+                    && descriptorToJavaType(classSubject.getFinalDescriptor()).equals(cnstString)) {
+                  return cnt + 1;
+                }
+              }
+              return cnt;
+            },
+            Integer::sum);
   }
 
   private static int countRenamedClassIdentifier(
@@ -316,22 +336,27 @@
         }, Integer::sum);
   }
 
-  private static Set<Instruction> getRenamedMemberIdentifierConstStrings(
-      ClassSubject clazz, Instruction[] instructions) {
-    Set<Instruction> result = Sets.newIdentityHashSet();
-    getConstStringInstructions(instructions).forEach(instr -> {
-      String cnstString = retrieveString(instr);
-      clazz.forAllMethods(foundMethodSubject -> {
-        if (foundMethodSubject.getFinalSignature().name.equals(cnstString)) {
-          result.add(instr);
-        }
-      });
-      clazz.forAllFields(foundFieldSubject -> {
-        if (foundFieldSubject.getFinalSignature().name.equals(cnstString)) {
-          result.add(instr);
-        }
-      });
-    });
+  private static Set<InstructionSubject> getRenamedMemberIdentifierConstStrings(
+      ClassSubject clazz, FoundMethodSubject method) {
+    Set<InstructionSubject> result = Sets.newIdentityHashSet();
+    getConstStringInstructions(method)
+        .forEach(
+            instr -> {
+              String cnstString =
+                  ((ConstStringInstructionSubject) instr).getString().toSourceString();
+              clazz.forAllMethods(
+                  foundMethodSubject -> {
+                    if (foundMethodSubject.getFinalSignature().name.equals(cnstString)) {
+                      result.add(instr);
+                    }
+                  });
+              clazz.forAllFields(
+                  foundFieldSubject -> {
+                    if (foundFieldSubject.getFinalSignature().name.equals(cnstString)) {
+                      result.add(instr);
+                    }
+                  });
+            });
     return result;
   }
 
diff --git a/src/test/java/com/android/tools/r8/neverreturnsnormally/NeverReturnsNormallyTest.java b/src/test/java/com/android/tools/r8/neverreturnsnormally/NeverReturnsNormallyTest.java
index 8ae31f7..1251972 100644
--- a/src/test/java/com/android/tools/r8/neverreturnsnormally/NeverReturnsNormallyTest.java
+++ b/src/test/java/com/android/tools/r8/neverreturnsnormally/NeverReturnsNormallyTest.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.utils.dexinspector.DexInspector;
 import com.android.tools.r8.utils.dexinspector.DexInstructionSubject;
 import com.android.tools.r8.utils.dexinspector.InstructionSubject;
+import com.android.tools.r8.utils.dexinspector.InstructionSubject.JumboStringMode;
 import com.android.tools.r8.utils.dexinspector.InvokeInstructionSubject;
 import com.android.tools.r8.utils.dexinspector.MethodSubject;
 import com.google.common.collect.ImmutableList;
@@ -78,7 +79,7 @@
     assertTrue(methodThrowToBeInlined.isPresent());
     Iterator<InstructionSubject> instructions = methodThrowToBeInlined.iterateInstructions();
     // Call, followed by throw null.
-    assertTrue(nextInstruction(instructions).isConstString());
+    assertTrue(nextInstruction(instructions).isConstString(JumboStringMode.ALLOW));
     InstructionSubject insn = nextInstruction(instructions);
     assertTrue(insn.isInvoke());
     assertTrue(((InvokeInstructionSubject) insn)
@@ -101,7 +102,7 @@
           .invokedMethod().name.toString().equals("throwToBeInlined"));
     } else {
       // Inlined code from throwToBeInlined.
-      assertTrue(nextInstruction(instructions).isConstString());
+      assertTrue(nextInstruction(instructions).isConstString(JumboStringMode.ALLOW));
       insn = nextInstruction(instructions);
       assertTrue(insn.isInvoke());
       assertTrue(((InvokeInstructionSubject) insn)
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java
index ae900f3..377f4d6 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java
@@ -55,13 +55,14 @@
   }
 
   @Override
-  public boolean isConstString() {
+  public boolean isConstString(JumboStringMode jumboStringMode) {
     return instruction instanceof CfConstString;
   }
 
   @Override
-  public boolean isConstString(String value) {
-    return isConstString() && ((CfConstString) instruction).getString().toString().equals(value);
+  public boolean isConstString(String value, JumboStringMode jumboStringMode) {
+    return isConstString(jumboStringMode)
+        && ((CfConstString) instruction).getString().toSourceString().equals(value);
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringCfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringCfInstructionSubject.java
new file mode 100644
index 0000000..96ece69
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringCfInstructionSubject.java
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, 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.utils.dexinspector;
+
+import com.android.tools.r8.cf.code.CfConstString;
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.graph.DexString;
+
+public class ConstStringCfInstructionSubject extends CfInstructionSubject
+    implements ConstStringInstructionSubject {
+  public ConstStringCfInstructionSubject(CfInstruction instruction) {
+    super(instruction);
+    assert isConstString(JumboStringMode.ALLOW);
+  }
+
+  @Override
+  public DexString getString() {
+    return ((CfConstString) instruction).getString();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringDexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringDexInstructionSubject.java
new file mode 100644
index 0000000..c4e7260
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringDexInstructionSubject.java
@@ -0,0 +1,28 @@
+// Copyright (c) 2018, 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.utils.dexinspector;
+
+import com.android.tools.r8.code.ConstString;
+import com.android.tools.r8.code.ConstStringJumbo;
+import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.graph.DexString;
+
+public class ConstStringDexInstructionSubject extends DexInstructionSubject
+    implements ConstStringInstructionSubject {
+  public ConstStringDexInstructionSubject(Instruction instruction) {
+    super(instruction);
+    assert isConstString(JumboStringMode.ALLOW);
+  }
+
+  @Override
+  public DexString getString() {
+    if (instruction instanceof ConstString) {
+      return ((ConstString) instruction).getString();
+    } else {
+      assert (instruction instanceof ConstStringJumbo);
+      return ((ConstStringJumbo) instruction).getString();
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringInstructionSubject.java
new file mode 100644
index 0000000..db454c2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/ConstStringInstructionSubject.java
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, 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.utils.dexinspector;
+
+import com.android.tools.r8.graph.DexString;
+
+public interface ConstStringInstructionSubject extends InstructionSubject {
+  DexString getString();
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInspector.java b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInspector.java
index c67a560..2a651e1 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInspector.java
@@ -30,6 +30,7 @@
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Timing;
+import com.android.tools.r8.utils.dexinspector.InstructionSubject.JumboStringMode;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
@@ -254,6 +255,8 @@
       return new FieldAccessDexInstructionSubject(this, instruction);
     } else if (dexInst.isNewInstance()) {
       return new NewInstanceDexInstructionSubject(instruction);
+    } else if (dexInst.isConstString(JumboStringMode.ALLOW)) {
+      return new ConstStringDexInstructionSubject(instruction);
     } else {
       return dexInst;
     }
@@ -267,6 +270,8 @@
       return new FieldAccessCfInstructionSubject(this, instruction);
     } else if (cfInst.isNewInstance()) {
       return new NewInstanceCfInstructionSubject(instruction);
+    } else if (cfInst.isConstString(JumboStringMode.ALLOW)) {
+      return new ConstStringCfInstructionSubject(instruction);
     } else {
       return cfInst;
     }
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionSubject.java
index 82d725a..2e558ae 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionSubject.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.code.Const4;
 import com.android.tools.r8.code.ConstString;
+import com.android.tools.r8.code.ConstStringJumbo;
 import com.android.tools.r8.code.Goto;
 import com.android.tools.r8.code.IfEqz;
 import com.android.tools.r8.code.IfNez;
@@ -86,14 +87,18 @@
   }
 
   @Override
-  public boolean isConstString() {
-    return instruction instanceof ConstString;
+  public boolean isConstString(JumboStringMode jumboStringMode) {
+    return instruction instanceof ConstString
+        || (jumboStringMode == JumboStringMode.ALLOW && instruction instanceof ConstStringJumbo);
   }
 
   @Override
-  public boolean isConstString(String value) {
-    return instruction instanceof ConstString
-        && ((ConstString) instruction).BBBB.toSourceString().equals(value);
+  public boolean isConstString(String value, JumboStringMode jumboStringMode) {
+    return (instruction instanceof ConstString
+            && ((ConstString) instruction).BBBB.toSourceString().equals(value))
+        || (jumboStringMode == JumboStringMode.ALLOW
+            && instruction instanceof ConstStringJumbo
+            && ((ConstStringJumbo) instruction).BBBBBBBB.toSourceString().equals(value));
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessCfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessCfInstructionSubject.java
index a2103e6..66dc877 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessCfInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessCfInstructionSubject.java
@@ -17,6 +17,7 @@
     assert isFieldAccess();
   }
 
+  @Override
   public TypeSubject holder() {
     return new TypeSubject(dexInspector, ((CfFieldInstruction) instruction).getField().getHolder());
   }
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessDexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessDexInstructionSubject.java
index ed54f90..52a51fe 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessDexInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessDexInstructionSubject.java
@@ -17,6 +17,7 @@
     assert isFieldAccess();
   }
 
+  @Override
   public TypeSubject holder() {
     return new TypeSubject(dexInspector, instruction.getField().getHolder());
   }
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/InstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/InstructionSubject.java
index b6f1e52..bf91974 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/InstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/InstructionSubject.java
@@ -5,6 +5,12 @@
 package com.android.tools.r8.utils.dexinspector;
 
 public interface InstructionSubject {
+
+  enum JumboStringMode {
+    ALLOW,
+    DISALLOW
+  };
+
   boolean isFieldAccess();
 
   boolean isInvokeVirtual();
@@ -15,9 +21,9 @@
 
   boolean isNop();
 
-  boolean isConstString();
+  boolean isConstString(JumboStringMode jumboStringMode);
 
-  boolean isConstString(String value);
+  boolean isConstString(String value, JumboStringMode jumboStringMode);
 
   boolean isGoto();
 
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeCfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeCfInstructionSubject.java
index 4d245b2..0f08810 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeCfInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeCfInstructionSubject.java
@@ -19,10 +19,12 @@
     this.dexInspector = dexInspector;
   }
 
+  @Override
   public TypeSubject holder() {
     return new TypeSubject(dexInspector, invokedMethod().getHolder());
   }
 
+  @Override
   public DexMethod invokedMethod() {
     if (isInvokeDynamic()) {
       throw new Unimplemented(
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeDexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeDexInstructionSubject.java
index 51d0767..da649c9 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeDexInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeDexInstructionSubject.java
@@ -18,10 +18,12 @@
     assert isInvoke();
   }
 
+  @Override
   public TypeSubject holder() {
     return new TypeSubject(dexInspector, invokedMethod().getHolder());
   }
 
+  @Override
   public DexMethod invokedMethod() {
     return instruction.getMethod();
   }