Java Virtual Machine的NOP
操作码在今天的Java虚拟机中有什么实际用途吗?如果是这样,在字节码中生成NOP
的场景是什么?
我甚至有兴趣看到一个用NOP
编译成字节码的Java代码示例。
更新
BCEL的MethodGen类说,
在生成代码时,可能需要插入
操作。
我猜其他字节码生成库也在同一条船上,正如公认的答案所指出的那样。
发布于 2012-05-03 22:19:46
一些NOP
字节码使用案例用于class
文件转换、优化和由Apache BCEL、ASM、FindBugs、PMD等工具执行的静态分析。Apache BCEL manual涉及到NOP
的一些用途,用于分析和优化目的。
虚拟机可以使用NOP
字节码进行即时优化,以确保处于同步安全点的代码块被正确对齐,从而避免false sharing。
至于一些使用包含NOP
字节码的JDK javac
编译器编译的示例代码,这是一个有趣的挑战。但是,我怀疑编译器是否会生成任何包含the bytecode instruction stream is only single-byte aligned
之后的NOP
字节码的class
文件。我很好奇能看到这样的例子,但我自己想不出任何例子。
发布于 2015-10-23 02:56:52
下面是我一直在研究的一些代码中的一个示例,其中nop指令被放入字节码中(正如Eclipse的字节码Visualizer所看到的那样)。
原始代码
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;
}
我不确定为什么要插入这些内容。我只希望它们不会对性能产生负面影响。
发布于 2012-05-03 06:19:06
通常不会为处理器流水线优化添加任何操作。我不确定Java目前在多大程度上使用它们。
最常用于计时目的,强制内存对齐,防止危险,占用分支延迟槽,或用作稍后在程序开发中由活动指令替换的占位符(或在重构有问题或耗时时替换移除的指令)。在某些情况下,NOP可能有轻微的副作用;例如,在摩托罗拉68000系列处理器上,NOP操作码会导致流水线的同步。
https://stackoverflow.com/questions/10422086
复制相似问题