13.10.2014 Views

OPTIMIZING THE JAVA VIRTUAL MACHINE INSTRUCTION SET BY ...

OPTIMIZING THE JAVA VIRTUAL MACHINE INSTRUCTION SET BY ...

OPTIMIZING THE JAVA VIRTUAL MACHINE INSTRUCTION SET BY ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

174<br />

// istore_1:<br />

local_vars[1] = stack[sp];<br />

// iload_1:<br />

stack[sp] = local_vars[1];<br />

With the stack adjustments removed, it becomes apparent that the second assignment<br />

is redundant. Generalizing, the first assignment is of the form A = B while<br />

the second is of the form B = A. Since B is a stack location which is only accessible<br />

within the current thread of execution, there is no possibility that the value of B has<br />

changed since it was written by the previous assignment. Consequently, the second<br />

assignment can be removed.<br />

A similar argument holds for the case where B is a local variable. Because local<br />

variables are part of the call stack entry for a method, they are also inaccessible to<br />

other threads of execution. As a result, there is no possibility that the value of B has<br />

been updated in this case either. The codelet representing the multicode istore 1<br />

iload 1 after the redundant assignment has been removed is shown below.<br />

// istore_1:<br />

local_vars[1] = stack[sp];<br />

// iload_1:<br />

Examining the assembly language code generated before and after the redundant<br />

assignment has been removed from the codelet reveals that removing the assignment<br />

results in a shorter assembly language code segment. When the second assignment<br />

is present, the optimizer in g++ is unable to determine that the second assignment is<br />

redundant. Consequently, an extra statement is generated in order to store a value in<br />

a register into the memory location for stack[sp]. The author speculates that this<br />

is the case because g++ is unaware that access to the local array is restricted to the<br />

current thread of execution. Thus the compiler is unable to determine conclusively<br />

that the value of local vars[1] has not changed between the statements.<br />

Unfortunately there are many sequences of bytecodes that cannot be optimized as<br />

much as the examples presented here. Sometimes such sequences do not optimize well<br />

because the adjacent bytecodes have minimal interaction with each other such as the<br />

process of loading several values onto the stack in preparation for invoking a method.<br />

In other cases, the optimization process becomes difficult because the sequence of<br />

bytecodes includes complex operations such as method invocations or field accesses.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!