private int calculateReservedCount(Dop[] opcodes) {
    int size = insns.size();

    /*
     * Potential new value of reservedCount, which gets updated in the
     * following loop. It starts out with the existing reservedCount
     * and gets increased if it turns out that additional registers
     * need to be reserved.
     */
    int newReservedCount = reservedCount;

    for (int i = 0; i < size; i++) {
      DalvInsn insn = insns.get(i);
      Dop originalOpcode = opcodes[i];
      Dop newOpcode = findOpcodeForInsn(insn, originalOpcode);

      if (newOpcode == null) {
        /*
         * The instruction will need to be expanded, so find the
         * expanded opcode and reserve registers for it.
         */
        Dop expandedOp = findExpandedOpcodeForInsn(insn);
        BitSet compatRegs = expandedOp.getFormat().compatibleRegs(insn);
        int reserve = insn.getMinimumRegisterRequirement(compatRegs);
        if (reserve > newReservedCount) {
          newReservedCount = reserve;
        }
      } else if (originalOpcode == newOpcode) {
        continue;
      }

      opcodes[i] = newOpcode;
    }

    return newReservedCount;
  }
Helper for {@link #reserveRegisters}, which does one pass over the instructions, calculating
the number of registers that need to be reserved. It also updates the {@code opcodes} list to
help avoid extra work in future register reservation passes.

@param opcodes {@code non-null;} array of per-instruction opcode selections
@return {@code >= 0;} the count of reserved registers
android/android_framework/dex-maker/src/main/java/com/android/dx/dex/code/OutputFinisher.java