Why does java bytecode “store” often followed by “load”?

会有一股神秘感。 提交于 2019-12-08 18:12:43

问题


When I read jvm bytecode which from some small java function, I found that when a new local variable is caculated on the operand stack, assuming that it will be stored in the local variable table, but usually it will be loaded to the operand stack immediately (just in the terms of bytecode literally). I don't understand the operation well, is it unnecessary operation?


回答1:


The Java compiler tends to compile things in a very simple and straightforward manner, leaving optimization to the JIT.

For example, if you write x *= 3; x *= 4;, you'll probably get bytecode along the lines of

iload_1
iconst_3
imul
istore_1
iload_1
iconst_4
imul
istore_1

The compiler could theoretically figure out that the store/load pair is redundant and remove it. But there are several reasons to not do so - 1) this adds a lot of complexity for no benefit as the JIT optimizes everything anyway 2) it makes debugging harder, since you no longer have access to the values of all the local variables 3) if an exception is somehow thrown in the middle of this expression, the local variables will have the incorrect values.




回答2:


Looking at the dspin bytecode

Method void dspin()
0   dconst_0       // Push double constant 0.0
1   dstore_1       // Store into local variables 1 and 2
2   goto 9         // First time through don't increment
5   dload_1        // Push local variables 1 and 2 
6   dconst_1       // Push double constant 1.0 
7   dadd           // Add; there is no dinc instruction
8   dstore_1       // Store result in local variables 1 and 2
9   dload_1        // Push local variables 1 and 2 
10  ldc2_w #4      // Push double constant 100.0 
13  dcmpg          // There is no if_dcmplt instruction
14  iflt 5         // Compare and loop if less than (i < 100.0)
17  return         // Return void when done

The only load that follows store is at offset 9. You can see that offset 9 can be reached by two different paths: (1) from offset 2 with goto 9; and (2) sequentially from offset 8

dload_1 pushes the value of local variables 1 and 2 onto the operand stack (two variables because of double): in case (1) when trying to enter the loop for the first time, and in case (2) when trying to enter the loop at later points of time.

Interestingly, in this example if you delete all store and load the behavior of the program will not change. However, the Java compiler usually does not try to be smart. It compiles Java code more or less directly. In this case the local variable i directly corresponds to local variables 1 and 2.

See Optimization by Java Compiler for more information.




回答3:


See, every operation in JVM is done on operand stack. So whenever you have to perform any operation on a variable, you have to first load (pushed ) on the operand stack by load command and then perform operation.

This is why store is followed by load instruction in bytecode.



来源:https://stackoverflow.com/questions/42779752/why-does-java-bytecode-store-often-followed-by-load

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!