Before a class runs, the JVM verifies its bytecode: every instruction gets operands of the right types, the stack never overflows or underflows, and no branch lands in the middle of an instruction. Up to version 49 the verifier worked the types out itself, by following every path through the code. From version 50 the compiler writes down the types at each branch target in a StackMapTable attribute, and the verifier only checks them, in one pass.
Which verifier runs
| Version | Verification |
|---|---|
| 45 to 49 | By type inference. StackMapTable is not used. |
| 50 | By type checking against StackMapTable; if that fails, the JVM may fall back to type inference. |
| 51 and later | By type checking only. Every method whose code branches needs a StackMapTable, and jsr, jsr_w and ret may not appear. |
The rules are in chapter 4.10 of the JVM Specification. The explorer reads the frames and shows the types; it does not run the verifier.
StackMapTable
An attribute of a Code attribute, at most one. Each frame gives the
types in the local variables and on the operand stack at one offset in the code. A
frame is needed at every branch target, every exception handler and every instruction
that follows an unconditional branch. The first, implicit frame, at pc 0, comes from
the method descriptor: this (or UninitializedThis in a
constructor), then the parameters, with an empty stack.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | u2 | attribute_name_index | A Utf8 entry: StackMapTable |
| 2 | 4 | u4 | attribute_length | The length of the rest |
| 6 | 2 | u2 | number_of_entries | The number of frames |
| 8 | varies | stack_map_frame[] | entries | The frames, in increasing offset order |
Each frame is stored as the difference from the frame before it. Its offset is
offset_delta for the first frame, and the previous frame’s offset +
offset_delta + 1 after that, so two frames can never share an offset.
The frame’s first byte, frame_type, decides its kind:
| frame_type | Kind | offset_delta | Locals | Stack |
|---|---|---|---|---|
| 0 to 63 | same_frame | frame_type | as before | empty |
| 64 to 127 | same_locals_1_stack_item_frame | frame_type − 64 | as before | one item |
| 128 to 246 | reserved | |||
| 247 | same_locals_1_stack_item_frame_extended | u2 | as before | one item |
| 248 to 250 | chop_frame | u2 | the last 1 to 3 removed | empty |
| 251 | same_frame_extended | u2 | as before | empty |
| 252 to 254 | append_frame | u2 | 1 to 3 added | empty |
| 255 | full_frame | u2 | all given | all given |
Types 128 to 246 are reserved. Project Valhalla’s preview builds use 246 for an “early larval” frame; that is not part of any released format, and the explorer turns down a frame of any reserved type.
same_frame (0 to 63)
The same locals as the previous frame and an empty stack. One byte.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 1 | u1 | frame_type | 0 to 63, which is also the offset_delta |
same_locals_1_stack_item_frame (64 to 127)
The same locals and one item on the stack, as at the start of an exception handler or after a branch that leaves a value.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 1 | u1 | frame_type | 64 to 127; offset_delta is frame_type − 64 |
| 1 | 1 or 3 | verification_type_info | stack[0] | The stack item |
same_locals_1_stack_item_frame_extended (247)
As the frame before, for an offset_delta too big for one byte.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 1 | u1 | frame_type | 247 |
| 1 | 2 | u2 | offset_delta | |
| 3 | 1 or 3 | verification_type_info | stack[0] | The stack item |
chop_frame (248 to 250)
The previous frame’s locals without the last k of them, where k is 251 − frame_type (1, 2 or 3), and an empty stack: the end of a block whose variables have gone out of scope.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 1 | u1 | frame_type | 248 to 250 |
| 1 | 2 | u2 | offset_delta |
same_frame_extended (251)
A same_frame for an offset_delta of 64 or more.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 1 | u1 | frame_type | 251 |
| 1 | 2 | u2 | offset_delta |
append_frame (252 to 254)
The previous frame’s locals with k more after them, where k is frame_type − 251 (1, 2 or 3), and an empty stack: the start of a block that declares new variables.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 1 | u1 | frame_type | 252 to 254 |
| 1 | 2 | u2 | offset_delta | |
| 3 | varies | verification_type_info[k] | locals | The added locals |
full_frame (255)
Everything given in full, when no shorter form fits.
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 1 | u1 | frame_type | 255 |
| 1 | 2 | u2 | offset_delta | |
| 3 | 2 | u2 | number_of_locals | The number of entries in locals |
| 5 | varies | verification_type_info[] | locals | The locals, from slot 0 |
| … | 2 | u2 | number_of_stack_items | The number of entries in stack |
| … | varies | verification_type_info[] | stack | The stack, from the bottom |
Verification types
Each local and stack item is a verification_type_info: a one-byte tag,
followed by two more bytes for two of the tags.
| Tag | Type | Then | Meaning |
|---|---|---|---|
| 0 | Top | Unusable: no value, or a slot the verifier cannot type | |
| 1 | Integer | An int, which also stands for boolean, byte, char and short | |
| 2 | Float | A float | |
| 3 | Double | A double; covers two slots | |
| 4 | Long | A long; covers two slots | |
| 5 | Null | The null reference | |
| 6 | UninitializedThis | this in a constructor, before the superclass constructor has run | |
| 7 | Object | u2 cpool_index | An instance of the class named by a Class entry (which may be an array type) |
| 8 | Uninitialized | u2 offset | An object made by the new instruction at that offset, whose constructor has not run yet |
A Long or Double written as one entry stands for two slots: in the locals, the slot
after it holds Top and is not written out. So a full_frame’s
number_of_locals can be smaller than the number of slots it covers.
A worked example
The method static int abs(int x) { return x < 0 ? -x : x; } compiles
to 11 bytes of code with two branch targets, at pc 9 and pc 10:
0: iload_0 1A
1: ifge 9 9C 00 08
4: iload_0 1A
5: ineg 74
6: goto 10 A7 00 04
9: iload_0 1A
10: ireturn AC
The implicit first frame has one local, the int x, and an empty stack.
Its StackMapTable body is five bytes, 00 02 09 40 01:
| Bytes | Field | Meaning |
|---|---|---|
00 02 | number_of_entries | 2 frames |
09 | frame 0: same_frame | offset_delta 9, so pc 9: locals [int], stack empty |
40 01 | frame 1: same_locals_1_stack_item_frame | offset_delta 64 − 64 = 0, so pc 9 + 0 + 1 = 10; stack [Integer] |
StackMap (Java ME)
Before StackMapTable, the CLDC configuration of Java ME used the same idea for phones,
whose virtual machine, the KVM, was too small to run the full verifier. The CLDC
preverifier adds a StackMap attribute to each Code attribute. It is not
part of the JVM Specification, and a Java SE virtual machine ignores it. The explorer
reads it with this layout, which fits every StackMap attribute in the class files
examined for this site exactly:
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 6 | 2 | u2 | number_of_entries | The number of frames |
| … | 2 | u2 | byte_code_offset | The frame’s offset in the code, as a plain number, not a delta |
| … | 2 | u2 | number_of_locals | The number of locals |
| … | varies | verification_type_info[] | locals | The locals, with the same tags as above |
| … | 2 | u2 | number_of_stack_items | The number of stack items |
| … | varies | verification_type_info[] | stack | The stack items |
The last five fields repeat for each frame. The layout is defined in the CLDC specification (JSR 139).