Assign temporary register to the size of an array.

Temporary register was added so that the value of existing registers
could remain the same.

Test: Dexfuzz was run.

Before
000144: 1300 0800                  |0000: const/16 v0, #int 8 // #8
000148: 2300 0300                  |0002: new-array v0, v0, [I // type@0003
00014c: 2600 0400 0000             |0004: fill-array-data v0, 00000008 // +00000004
000152: 1100                       |0007: return-object v0

After
000144: 0900 0100 0200             |0000: move-object/16 v1, v2
00014a: 1300 1052                  |0003: const/16 v0, #int 21008 // #5210
00014e: 1302 1800                  |0005: const/16 v2, #int 24 // #18
000152: 2320 0300                  |0007: new-array v0, v2, [I // type@0003
000156: 2600 0500 0000             |0009: fill-array-data v0, 0000000e // +00000005
00015c: 1102                       |000c: return-object v2

Change-Id: I0d8380ab3facd6256bc46931929d32763bad4476
diff --git a/tools/dexfuzz/src/dexfuzz/DexFuzz.java b/tools/dexfuzz/src/dexfuzz/DexFuzz.java
index d37bd34..b0ce5a8 100644
--- a/tools/dexfuzz/src/dexfuzz/DexFuzz.java
+++ b/tools/dexfuzz/src/dexfuzz/DexFuzz.java
@@ -33,9 +33,9 @@
  * Entrypoint class for dexfuzz.
  */
 public class DexFuzz {
-  // Last version update 1.5: added register clobber mutator.
+  // Last version update 1.6: added temporary register to ArrayLengthChanger.
   private static int majorVersion = 1;
-  private static int minorVersion = 5;
+  private static int minorVersion = 6;
   private static int seedChangeVersion = 0;
 
   /**
diff --git a/tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java b/tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java
index aba7971..e640b4e 100644
--- a/tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java
+++ b/tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java
@@ -28,8 +28,6 @@
 import java.util.List;
 import java.util.Random;
 
-// This mutation might change the length of an array but can also change the
-// value of the register in every place it is used.
 public class NewArrayLengthChanger extends CodeMutator {
   /**
    * Every CodeMutator has an AssociatedMutation, representing the
@@ -116,20 +114,46 @@
     MutatableCode mutatableCode = mutation.mutatableCode;
     MInsn newArrayInsn = newArrayLengthInsns.get(mutation.newArrayToChangeIdx);
     int newArrayInsnIdx = mutatableCode.getInstructionIndex(newArrayInsn);
+    // If the original new-array instruction is no longer present
+    // in the code (as indicated by a negative index), we make a
+    // best effort to find any other new-array instruction to
+    // apply the mutation to. If that effort fails, we simply
+    // bail by doing nothing.
+    if (newArrayInsnIdx < 0) {
+      newArrayInsnIdx = scanNewArray(mutatableCode);
+      if (newArrayInsnIdx == -1) {
+        return;
+      }
+    }
 
     MInsn newInsn = new MInsn();
     newInsn.insn = new Instruction();
     newInsn.insn.info = Instruction.getOpcodeInfo(Opcode.CONST_16);
+    mutatableCode.allocateTemporaryVRegs(1);
+    newArrayInsn.insn.vregB = mutatableCode.getTemporaryVReg(0);
     newInsn.insn.vregA = (int) newArrayInsn.insn.vregB;
     // New length chosen randomly between 1 to 100.
     newInsn.insn.vregB = rng.nextInt(100);
     mutatableCode.insertInstructionAt(newInsn, newArrayInsnIdx);
     Log.info("Changed the length of the array to " + newInsn.insn.vregB);
     stats.incrementStat("Changed length of new array");
+    mutatableCode.finishedUsingTemporaryVRegs();
   }
 
   private boolean isNewArray(MInsn mInsn) {
     Opcode opcode = mInsn.insn.info.opcode;
     return opcode == Opcode.NEW_ARRAY;
   }
+
+  // Return the index of first new-array in the method, -1 otherwise.
+  private int scanNewArray(MutatableCode mutatableCode) {
+    int idx = 0;
+    for (MInsn mInsn : mutatableCode.getInstructions()) {
+      if (isNewArray(mInsn)) {
+        return idx;
+      }
+      idx++;
+    }
+    return -1;
+  }
 }
\ No newline at end of file