Для чего используется NOP в байт-коде JVM?
Есть ли практическое использование виртуальной машины Java? NOP
код операции в сегодняшней JVM? Если да, то каковы некоторые сценарии, в которых NOP
s будет сгенерирован в байт-код?
Мне даже было бы интересно увидеть пример кода Java, который компилируется в байт-код с NOP
s.
Обновить
Класс MethodGen BCEL говорит,
При создании кода может потребоваться вставить операции NOP.
Я предполагаю, что другие библиотеки генерации байт-кода находятся в одной лодке, как было указано в принятом ответе.
3 ответа
Немного 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
, Мне было бы любопытно увидеть такой пример, но я не могу думать ни о чем себе.
Вот пример из некоторого кода, над которым я работал, где инструкции nop помещены в байт-код (как видно из Bytecode Visualizer for 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;
}
Я не уверен, почему они будут вставлены. Я просто надеюсь, что они не влияют отрицательно на производительность.
Для оптимизации конвейера процессора часто не добавляются операции. Я не уверен, в какой степени Java использует их в настоящее время.
Из Википедии:
NOP чаще всего используется для целей синхронизации, для принудительного выравнивания памяти, для предотвращения опасностей, для того, чтобы занять место задержки ветвления, или в качестве заполнителя, который должен быть заменен активными инструкциями позже в процессе разработки программы (или для замены удаленных инструкций, когда рефакторинг будет проблематичным или трудоемким). В некоторых случаях NOP может иметь незначительные побочные эффекты; например, на процессорах серии Motorola 68000 код операции NOP вызывает синхронизацию конвейера.