/**
   * Add an instruction to the peephole window. If the window is already full then the first
   * instruction will be removed, and passed on to the next delegate to make room for the new
   * instruction
   *
   * @param insn the Instruction to add
   */
  private void addInstruction(Instruction insn) {
    int size = instructions.size();
    InstructionInfo info = null;
    if (size == PEEPHOLE_WINDOW_SIZE) {
      // reuse the InstructionInfo if we can
      info = instructions.remove(0);
      finishInstruction(info);

      if (lastLabelSeen != NO_LABEL) --lastLabelSeen;
    } else {
      info = new InstructionInfo();
    }
    info.reset(insn);
    instructions.add(info);

    if (labelsFromDeletedInsns != null) {
      // If we saved any labels from a deleted instruction sequence,
      // apply them here.
      // They will always be label currents no matter what the started out
      // as - if we deleted something with a labelNext, this is still the next instruction
      // and if we deleted something with a labelCurrent then this instruction is the new current
      // instruction
      for (Label l : labelsFromDeletedInsns) labelCurrent(l);
      labelsFromDeletedInsns = null;
    }
  }