public void startLocal(int address, RegisterSpec startedLocal) {
      if (DEBUG) {
        System.err.printf("%04x start %s\n", address, startedLocal);
      }

      int regNum = startedLocal.getReg();

      startedLocal = filterSpec(startedLocal);
      aboutToProcess(address, regNum);

      RegisterSpec existingLocal = regs.get(regNum);

      if (startedLocal.equalsUsingSimpleType(existingLocal)) {
        // Silently ignore a redundant start.
        return;
      }

      RegisterSpec movedLocal = regs.findMatchingLocal(startedLocal);
      if (movedLocal != null) {
        /*
         * The same variable was moved from one register to another.
         * So add an end for its old location.
         */
        addOrUpdateEnd(address, Disposition.END_MOVED, movedLocal);
      }

      int endAt = endIndices[regNum];

      if (existingLocal != null) {
        /*
         * There is an existing (but non-matching) local.
         * Add an explicit end for it.
         */
        add(address, Disposition.END_REPLACED, existingLocal);
      } else if (endAt >= 0) {
        /*
         * Look for an end local for the same register at the
         * same address. If found, then update it or delete
         * it, depending on whether or not it represents the
         * same variable as the one being started.
         */
        Entry endEntry = result.get(endAt);
        if (endEntry.getAddress() == address) {
          if (endEntry.matches(startedLocal)) {
            /*
             * There was already an end local for the same
             * variable at the same address. This turns
             * out to be superfluous, as we are starting
             * up the exact same local. This situation can
             * happen when a single local variable got
             * somehow "split up" during intermediate
             * processing. In any case, rather than represent
             * the end-then-start, just remove the old end.
             */
            result.set(endAt, null);
            nullResultCount++;
            regs.put(startedLocal);
            endIndices[regNum] = -1;
            return;
          } else {
            /*
             * There was a different variable ended at the
             * same address. Update it to indicate that
             * it was ended due to a replacement (rather than
             * ending for no particular reason).
             */
            endEntry = endEntry.withDisposition(Disposition.END_REPLACED);
            result.set(endAt, endEntry);
          }
        }
      }

      /*
       * The code above didn't find and remove an unnecessary
       * local end, so we now have to add one or more entries to
       * the output to capture the transition.
       */

      /*
       * If the local just below (in the register set at reg-1)
       * is of category-2, then it is ended by this new start.
       */
      if (regNum > 0) {
        RegisterSpec justBelow = regs.get(regNum - 1);
        if ((justBelow != null) && justBelow.isCategory2()) {
          addOrUpdateEnd(address, Disposition.END_CLOBBERED_BY_NEXT, justBelow);
        }
      }

      /*
       * Similarly, if this local is category-2, then the local
       * just above (if any) is ended by the start now being
       * emitted.
       */
      if (startedLocal.isCategory2()) {
        RegisterSpec justAbove = regs.get(regNum + 1);
        if (justAbove != null) {
          addOrUpdateEnd(address, Disposition.END_CLOBBERED_BY_PREV, justAbove);
        }
      }

      /*
       * TODO: Add an end for the same local in a different reg,
       * if any (that is, if the local migrates from vX to vY,
       * we should note that as a local end in vX).
       */

      add(address, Disposition.START, startedLocal);
    }
Starts a local at the given address.

@param address {@code >= 0;} the address
@param startedLocal {@code non-null;} spec representing the started local
android/android_framework/dex-maker/src/main/java/com/android/dx/dex/code/LocalList.java