The Joy of
Programming S.G. GaneSh
Traps and Pitfalls: Swapping Two Variables— Part IV
Last month, we covered an interesting issue in swapping variables without a temporary in a single
statement and saw that the trick does not work in Java. This month, we’ll look at what happens
behind the scenes in the JVM by analysing the byte codes generated for the statement.
ast month, we introduced a problem in Java: given instruction duplicates the value in the top of the stack.
two integers i and j, the following statement does Now, let us simulate the execution of instructions. On
not swap the values of two variables correctly i ^= top is the execution stack and its state; at the bottom is
(j ^= (i ^= j)). the value for memory locations i and j, and is indicated by
To understand what is happening, let us analyse the ‘_1’ and ‘_2’.
byte code generated for this statement. How do we get Assume that the initial values of i and j are 3 and 6
the byte codes? By using the javap tool on the generated and hence _1 and _2 have the values 3 and 6, respectively,
class file, which will be available in the same directory as stored in them.
javac (in the bin directory). javap is a Java dis-assembler
tool that reads the Java class files and dumps the info in 1) Init 2) after 3) after 4) ixor 5) dup
a human-readable form. First issue the command, javac state executing executing
iload_1 & iload_1 &
Swap.java and then javap -c Swap; you’ll get the detailed iload_2 iload_2
output with byte codes.
From this output, here is the sequence of byte codes 6 5
generated for the statement i ^= (j ^= (i ^= j)): 3 5 5
6 6 6 6
39: iload_1 3 3 3 3
40: iload_2 3 6 3 6 3 6 3 6 3 6
i(_1) j(_2) i(_1) j(_2) i(_1) j(_2) i(_1) j(_2) i(_1) j(_2)
43: ixor 6) istore_1 7) after 8) istore_2 9) ixor 10) istore_1
ixor & dup
46: ixor 5 3
6 3 3
47: dup 3 3 3 0
48: istore_2 5 6 5 6 5 3 5 3 0 3
49: ixor i(_1) j(_2) i(_1) j(_2) i(_1) j(_2) i(_1) j(_2) i(_1) j(_2)
Here is a quick intro on byte codes. The intermediate As you can see, for the initial values of 3 and 6 for i
language for Java is byte codes. These are assembly and j, after execution of the instructions, the final values
language codes for an imaginary stack-based machine are 0 and 3, respectively. I hope that it is now clear how
(that is the reason why the Java runtime is called a ‘virtual the Java compiler translated the statement i ^= (j ^=
machine’). The size of an instruction is one byte, and hence (i ^= j)); and why the values of i and j are not swapped
the name ‘byte code’. correctly (which is according to the Java specifications).
There are only a few instructions that we need to Now, you can try the same process for the three
understand to interpret how this instruction sequence consecutive statements i ^= j; j ^= i; and i ^= j. You’ll
works. The instruction prefixed with i—as in iload realise that the compiler emits a different sequence
and istore—indicates that the instruction is meant of byte codes. You can also verify that this instruction
for integers (remember that i and j are integers). The sequence swaps the values of i and j correctly!
instructions iload and istore load and store an integer to
and from the ‘runtime execution stack’ and ‘local memory S.G. Ganesh is a research engineer at Siemens (Corporate
area in the stack’. Here the suffix _1 and _2 indicates Technology), Bangalore. His latest book is “60 Tips on
the first two local variables i and j. The instruction ixor Object Oriented Programming” (ISBN 978-0-07-065670-3),
published by Tata McGraw-Hill, New Delhi. You can reach
pops the values twice from the stack and X-ORs the
him at email@example.com
result and pushes the result back into the stack. The dup
12 juLY 2008 | LINuX For You | www.openITis.com