Что такое NOP для использования байт-кода JVM? - программирование
Подтвердить что ты не робот

Что такое NOP для использования байт-кода JVM?

Есть ли практическое использование кода виртуальной машины Java NOP в сегодняшнем JVM? Если да, то каковы сценарии, в которых NOP будет сгенерирован в байт-коде?

Мне даже было бы интересно увидеть пример кода Java, который компилируется в байт-код с помощью NOP s.


Обновление

BCEL MethodGen класс говорит,

При генерации кода может потребоваться вставить операции NOP.

Я предполагаю, что другие библиотеки генерации байткодов находятся в одной лодке, как было указано в принятом ответе.

4b9b3361

Ответ 1

Некоторые примеры использования <байт-кодa > NOP предназначены для class преобразований файлов, оптимизации и статического анализа, выполняемых такими инструментами, как Apache BCEL, ASM, FindBugs, PMD и т.д. Apache Руководство BCEL затрагивает некоторые виды использования NOP для целей анализа и оптимизации.

JVM может использовать NOP байт-коды для оптимизации JIT для обеспечения того, чтобы блоки кода, находящиеся в синхронизации, были правильно выровнены, чтобы избежать ложного обмена.

Как для некоторого примера кода, скомпилированного с использованием компилятора JDK javac, который содержит NOP байт-коды, это интересная задача. Однако я сомневаюсь, что компилятор сгенерирует любой файл class, содержащий NOP байт-коды, так как the bytecode instruction stream is only single-byte aligned. Мне было бы любопытно увидеть такой пример, но я не могу думать ни о себе.

Ответ 2

Вот пример из некоторого кода, над которым я работал, где nop-инструкции где помещается в байтовый код (если смотреть Bytecode Visualizer для Eclipse)

Исходный код

public abstract class Wrapper<T extends Wrapper<T,E>,E>
  implements Supplier<Optional<E>>, Consumer<E>
{
  /** The wrapped object. */
  protected Optional<E> inner;

  /*
   * (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  /**
   * A basic equals method that will compare the wrapped object to
   * whatever you throw at it, whether it is wrapped or not.
   */
  @Override
  public boolean equals(final Object that)
  {
    return this==that
        ||LambdaUtils.castAndMap(that,Wrapper.class,afterCast
            -> inner.equals(afterCast.inner))
        .orElseGet(()
            -> LambdaUtils.castAndMap(that,Optional.class,afterCast
                -> inner.equals(afterCast))
            .orElseGet(()
                -> Optional.ofNullable(that).map(thatobj
                    -> that.equals(inner.get()))
                .orElseGet(()
                    -> false)));
  }
}

Переведенный байтовый код для метода equals (Object)

public boolean equals(java.lang.Object arg0) {
    /* L27 */
    0 aload_0;                /* this */
    1 aload_1;                /* that */
    2 if_acmpeq 36;
    /* L28 */
    5 aload_1;                /* that */
    6 ldc 1;
    8 aload_0;                /* this */
    9 invokedynamic 29;       /* java.util.function.Function apply(ext.cat.wcutils.collections.Wrapper arg0) */
    12 nop;
    13 nop;
    14 invokestatic 30;       /* java.util.Optional ext.cat.wcutils.util.LambdaUtils.castAndMap(java.lang.Object arg0, java.lang.Class arg1, java.util.function.Function arg2) */
    /* L30 */
    17 aload_0;               /* this */
    18 aload_1;               /* that */
    19 invokedynamic 39;      /* java.util.function.Supplier get(ext.cat.wcutils.collections.Wrapper arg0, java.lang.Object arg1) */
    22 nop;
    23 nop;
    24 invokevirtual 40;      /* java.lang.Object orElseGet(java.util.function.Supplier arg0) */
    27 checkcast 46;          /* java.lang.Boolean */
    30 invokevirtual 48;      /* boolean booleanValue() */
    /* L37 */
    33 ifne 5;
    /* L27 */
    36 iconst_0;
    37 ireturn;
    38 iconst_1;
    39 ireturn;
}

Я не уверен, почему они будут вставлены. Я просто надеюсь, что они не будут отрицательно влиять на производительность.

Ответ 3

Для оптимизации конвейера процессора часто не добавляются операционные системы. Я не уверен, в какой мере Java использует их в настоящее время.

Из Wikipedia:

NOP чаще всего используется для целей синхронизации, чтобы заставить память выравнивание, предотвращение опасностей, занять интервал задержки ветвления или как place-holder, который будет заменен активными инструкциями позже в программе разработки (или заменить удаленные инструкции, когда рефакторинг будет быть проблематичным или трудоемким). В некоторых случаях NOP может иметь незначительные побочные эффекты; например, на процессорах Motorola 68000, код операции NOP вызывает синхронизацию конвейера.