java - que - qué función cumple la herramienta bytecode?
¿Para qué se utiliza NOP en el código de bytes JVM? (3)
A menudo no se agregan operaciones para las optimizaciones de la tubería del procesador. No estoy seguro de hasta qué punto Java los usa actualmente.
De Wikipedia :
Un NOP se usa más comúnmente para propósitos de tiempo, para forzar la alineación de la memoria, para prevenir peligros, para ocupar una ranura de retardo de derivación o para ser reemplazado por instrucciones activas más adelante en el desarrollo del programa (o para reemplazar instrucciones eliminadas cuando la refactorización sería problemática o requeriría mucho tiempo). En algunos casos, un NOP puede tener efectos secundarios menores; por ejemplo, en la serie de procesadores Motorola 68000, el código de operación NOP provoca una sincronización de la tubería.
¿Hay algún uso práctico del código de operación NOP
de la máquina virtual Java en la JVM de hoy? Si es así, ¿cuáles son algunos escenarios en los que los NOP
s se generarían en el bytecode?
Incluso me interesaría ver un ejemplo de código Java que se compile en un código de bytes con NOP
s.
Actualizar
La clase de MethodGen de MethodGen dice:
Mientras se genera el código, puede ser necesario insertar operaciones NOP.
Supongo que otras bibliotecas de generación de Bytecode están en el mismo barco, como se señaló en la respuesta aceptada.
Algunos casos de uso de código de bytes de NOP
son para transformaciones de archivos de class
, optimizaciones y análisis estático realizados por herramientas como Apache BCEL , ASM , FindBugs , PMD , etc. El manual de Apache BCEL incluye algunos usos de NOP
para fines de análisis y optimización.
Una JVM puede usar los NOP
byte NOP
para las optimizaciones JIT para garantizar que los bloques de códigos que se encuentran en la sincronización de seguridad estén alineados correctamente para evitar la falsa compartición .
En cuanto a algunos ejemplos de código compilado con el javac
JDK javac
que contiene códigos de javac
NOP
, ese es un desafío interesante. Sin embargo, dudo que el compilador genere cualquier archivo de class
que contenga bytecodes NOP
ya que the bytecode instruction stream is only single-byte aligned
. Tendría curiosidad por ver un ejemplo así, pero no puedo pensar en ninguno.
Aquí hay un ejemplo de un código en el que he estado trabajando donde no se colocaron las instrucciones en el código de byte (tal como lo ve Bytecode Visualizer for Eclipse)
El codigo original
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)));
}
}
El código de byte traducido para el método equals (objeto)
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;
}
No estoy seguro de por qué esos serían insertados. Solo espero que no afecten negativamente el rendimiento.