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.

260<br />

ceptions continue to identify the correct locations within the code stream once a rule<br />

has been applied to it.<br />

Retaining the correct branch and exception semantics is accomplished within the<br />

class file mutator by representing the bytecode stream as an ordered list of instruction<br />

objects rather than a sequence of bytes. When the code stream is translated into a<br />

list, all branch targets are expressed as pointers to other objects in the list rather<br />

than as offsets within the code stream. The multicode substitution is performed<br />

on the list representation. Once the substitution is complete, the bytecode stream<br />

is generated from the list representation by performing two passes. The first pass<br />

determines the program counter value for each of the instructions, including any pad<br />

bytes that need to be introduced within tableswitch and lookupswitch bytecodes.<br />

The bytecode stream is generated during the second pass. At that time, the branch<br />

targets expressed as pointers are replaced with the difference between the program<br />

counter of the current instruction and the instruction that is the target of the branch.<br />

Entries in the exception table are handled in a similar manner. Items in the<br />

exception table are converted from program counter values to pointers into the list<br />

of bytecodes immediately after the list representation is generated. The program<br />

counter representation of the exception table is regenerated immediately after the list<br />

of bytecodes is converted back into a byte stream. Consequently, appropriate changes<br />

will be made to the program counter values specified in the exception table for any<br />

changes made to the bytecode list.<br />

Care is taken to ensure that the pointers to entries in the list of bytecodes remain<br />

valid as the list is manipulated. When despecializations are performed the internal<br />

operations do not deallocate the bytecode object representing the specialized bytecode<br />

and then allocate a new bytecode object to represent its general purpose form.<br />

Instead, the opcode and operand values of the bytecode object are modified so that<br />

the object represents the equivalent general purpose form. If the general purpose<br />

form is a sequence of bytecodes then new bytecode objects are allocated to represent<br />

the bytecodes in the sequence beyond the first. Performing the manipulation in this<br />

manner removes the need to update any pointers in other data structures because the<br />

object that was the specialized bytecode before the transformation is the first (and<br />

possibly only) bytecode in the despecialized form after the despecialization.<br />

A similar strategy is employed for multicode substitution. In this case, the objects<br />

representing the second bytecode in the sequence and beyond are deallocated. It was<br />

determined that none of these bytecodes are targets of any branches or exception<br />

handlers before the substitution process began. Consequently, it is guaranteed that

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

Saved successfully!

Ooh no, something went wrong!