/**
   * Should be notified every time byte-code is added to the machine.
   *
   * @param codeBuffer A buffer containing the byte-code.
   * @param start The start offset within the buffer of the new code.
   * @param length The length of the new code.
   * @param interner The machines interner to lookup interned names with.
   * @param codeView The machines code view to find interned names matching addresses.
   */
  public void onCodeUpdate(
      ByteBuffer codeBuffer,
      int start,
      int length,
      VariableAndFunctorInterner interner,
      WAMCodeView codeView) {
    log.fine(
        "public void onCodeUpdate(ByteBuffer codeBuffer, int start = "
            + start
            + ", int length = "
            + length
            + ", VariableAndFunctorInterner interner, WAMCodeView codeView): called");

    // Take a copy of the new bytecode.
    copyAndResizeCodeBuffer(codeBuffer, start, length);

    // Disassemble the new area of byte code.
    SizeableList<WAMInstruction> instructions =
        WAMInstruction.disassemble(start, length, this.codeBuffer, interner, codeView);

    // Figure out where to start writing the disassembled code into the table.
    Map.Entry<Integer, Integer> entry = addressToRow.floorEntry(start);
    int firstRow = (entry == null) ? 0 : (entry.getValue() + 1);

    int address = start;
    int row = firstRow;

    // Build the mapping between addresses and rows.
    for (WAMInstruction instruction : instructions) {
      addressToRow.put(address, row);
      rowToAddress.add(row, address);

      row++;
      address += instruction.sizeof();
    }

    // Render the instructions into the table to be displayed.
    renderInstructions(instructions, firstRow, start);
  }