0

The Java Class File Specification states that:

The code array gives the actual bytes of Java Virtual Machine code that implement the method.

When the code array is read into memory on a byte-addressable machine, if the first byte of the array is aligned on a 4-byte boundary, the tableswitch and lookupswitch 32-bit offsets will be 4-byte aligned. (Refer to the descriptions of those instructions for more information on the consequences of code array alignment.) (https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.3)

How would I interpret this statement?

The wikipedia page for those 2 instructions mentions this: (https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings)

Tableswitch additional bytes:

4+: [0–3 bytes padding], defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4, lowbyte1, lowbyte2, lowbyte3, lowbyte4, highbyte1, highbyte2, highbyte3, highbyte4, jump offsets...

Lookupswitch additional bytes:

4+: <0–3 bytes padding>, defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4, npairs1, npairs2, npairs3, npairs4, match-offset pairs...

I think the <0–3 bytes padding> is relevant to the Class File Specification statement, I just don't know how exactly.

1 Answer 1

1

The tableswitch and lookupswitch instructions are defined to have between 0 and 3 bytes of padding, depending on their offset within the method's bytecode. The actual definition of the padding can be found in section 6.5 where the formats of each instruction are listed.

Immediately after the lookupswitch opcode, between zero and three bytes must act as padding, such that defaultbyte1 begins at an address that is a multiple of four bytes from the start of the current method (the opcode of its first instruction).

The statement you highlighted explains the motivation for this design choice, which might otherwise seem odd or pointless.

This allows for a more efficient implementation of a Java interpreter, because if the code is loaded at a 4-byte aligned address, the offsets and keys in the switch tables can be read with aligned access.

Of course, it isn't that important nowadays, because we have fancy JITs, but back in the early days of Java, the JVM probably was implemented as a naive interpreter where this would make a big difference in performance.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! Weird how java is so old that these things were important back then
It could still be useful for the interpreted startup phase, if there wasn’t the conceptional issue that, when a class is loaded, the method’s instruction sequences aren’t aligned and when I have to copy the code for aligning it, I could insert the padding right when copying, if deemed beneficial. If I decide not to copy the code, the alignment is an unnecessary complication…
Well it saves you from having to adjust all the offsets if you insert padding.