The document provides an introduction to the Java Virtual Machine (JVM) bytecode and JIT compiler. It discusses how bytecode works, including inspection, generation and the bytecode instructions. It also covers how the JIT compiler works and is monitored. Examples of viewing bytecode with javap and generating bytecode with BiteScript are provided.
1 of 209
Downloaded 927 times
More Related Content
JVM for Dummies - OSCON 2011
1. JVM for Dummies
(and for the rest of you, as well)
Wednesday, July 27, 2011
2. Intro
• Charles Oliver Nutter
• “JRuby Guy”
• Sun Microsystems 2006-2009
• Engine Yard 2009-
• Primarily responsible for compiler, perf
• Lots of bytecode generation
• Lots of JIT monitoring
Wednesday, July 27, 2011
3. Today
• JVM Bytecode
• Inspection
• Generation
• How it works
• JVM JIT
• How it works
• Monitoring
• Assembly (don’t be scared!)
Wednesday, July 27, 2011
4. Today
• JVM Bytecode
•
•
•
Inspection
Generation } For Dummies
}
How it works
• JVM JIT
• How it works For people who want
• Monitoring to feel like Dummies
• Assembly
Wednesday, July 27, 2011
6. Bytecode Definition
• “... instruction sets designed for efficient
execution by a software interpreter ...”
• “... suitable for further compilation into
machine code.
Wednesday, July 27, 2011
7. Byte Code
• One-byte instructions
• 256 possible “opcodes”
• 200 in use on current JVMs
• Room for more :-)
• Little variation since Java 1.0
Wednesday, July 27, 2011
8. Microsoft’s CLR
• Stack-based, but not interpreted
• Two-byte “Wordcodes”
• Similar operations to JVM
Wednesday, July 27, 2011
9. Why Learn It
• Know your platform
• Full understanding from top to bottom
• Bytecode generation is fun and easy
• Build your own language?
• May need to read bytecode someday
• Many libraries generate bytecode
Wednesday, July 27, 2011
10. Hello World
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world");
}
}
Wednesday, July 27, 2011
11. javap
• Java class file disassembler
• Basic operation shows class structure
• Methods, superclasses, interface, etc
• -c flag includes bytecode
• -public, -private, -protected
• -verbose for stack size, locals, args
Wednesday, July 27, 2011
12. javap
~/projects/bytecode_for_dummies ➔ javap HelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld extends java.lang.Object{
public HelloWorld();
public static void main(java.lang.String[]);
}
Wednesday, July 27, 2011
13. javap -c
~/projects/bytecode_for_dummies ➔ javap -c HelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld extends java.lang.Object{
public HelloWorld();
Code:
0:! aload_0
1:! invokespecial!#1; //Method java/lang/Object."<init>":()V
4:! return
public static void main(java.lang.String[]);
Code:
0:! getstatic! #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3:! ldc!#3; //String Hello, world
5:! invokevirtual!#4; //Method java/io/PrintStream.println:
(Ljava/lang/String;)V
8:! return
}
Wednesday, July 27, 2011
14. javap -verbose
~/projects/bytecode_for_dummies ➔ javap -c -verbose HelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld extends java.lang.Object
SourceFile: "HelloWorld.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method! #6.#15;!// java/lang/Object."<init>":()V
const #2 = Field!#16.#17;! / java/lang/System.out:Ljava/io/PrintStream;
/
const #3 = String! #18;! / Hello, world
/
const #4 = Method! #19.#20;! / java/io/PrintStream.println:(Ljava/lang/String;)V
/
const #5 = class!#21;! / HelloWorld
/
...
{
Wednesday, July 27, 2011
15. javap -verbose
...
public HelloWorld();
Code:
Stack=1, Locals=1, Args_size=1
0:!aload_0
1:!invokespecial! #1; //Method java/lang/Object."<init>":()V
4:!return
LineNumberTable:
line 1: 0
Wednesday, July 27, 2011
16. javap -verbose
public static void main(java.lang.String[]);
Code:
Stack=2, Locals=1, Args_size=1
0:! getstatic!#2; //Field java/lang/System.out:Ljava/io/PrintStream;
3:! ldc!
#3; //String Hello, world
5:! invokevirtual!
#4; //Method java/io/PrintStream.println:
(Ljava/lang/String;)V
8:! return
LineNumberTable:
line 3: 0
line 4: 8
}
Wednesday, July 27, 2011
20. BiteScript
• (J)Ruby DSL for emitting JVM bytecode
• Internal DSL
• Primitive “macro” support
• Reads like javap -c (but nicer)
• http://github.com/headius/bitescript
Wednesday, July 27, 2011
21. Installation
• Download JRuby from http://jruby.org
• Unpack, optionally add bin/ to PATH
• Ahead of PATH if you have Ruby already
• [bin/]jruby -S gem install bitescript
• `bite myfile.bs` to run myfile.bs file
• `bitec myfile.bs` to compile myfile.bs file
Wednesday, July 27, 2011
22. BiteScript Users
• Mirah
• Ruby-like language for writing Java code
• BiteScript for JVM bytecode backend
• BrainF*ck implementation
• Other miscellaneous bytecode experiments
Wednesday, July 27, 2011
23. javap -c
~/projects/bytecode_for_dummies ➔ javap -c HelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld extends java.lang.Object{
public HelloWorld();
Code:
0:! aload_0
1:! invokespecial!#1; //Method java/lang/Object."<init>":()V
4:! return
public static void main(java.lang.String[]);
Code:
0:! getstatic! #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3:! ldc!#3; //String Hello, world
5:! invokevirtual!#4; //Method java/io/PrintStream.println:
(Ljava/lang/String;)V
8:! return
}
Wednesday, July 27, 2011
24. BiteScript
main do
getstatic java.lang.System, "out",
java.io.PrintStream
ldc "Hello, world!"
invokevirtual java.io.PrintStream, "println",
[java.lang.Void::TYPE, java.lang.Object]
returnvoid
end
Wednesday, July 27, 2011
25. BiteScript
import java.lang.System JRuby’s “import”
import java.io.PrintStream for Java classes
main do
getstatic System, "out", PrintStream
ldc "Hello, world!"
invokevirtual PrintStream, "println", [void, object]
returnvoid
end
Shortcuts for
void, int, string,
object, etc
Wednesday, July 27, 2011
26. BiteScript
main do
ldc "Hello, world!"
aprintln
returnvoid A BiteScript “macro”
end
Wednesday, July 27, 2011
27. BiteScript
macro :aprintln do
getstatic System, "out", PrintStream
swap
invokevirtual PrintStream, "println",
[void, object]
end
Wednesday, July 27, 2011
28. The Basics
• Stack machine
• Basic operations
• Flow control
• Class structures
• Exception handling
Wednesday, July 27, 2011
29. Stack Machine
• The “operand stack” holds operands
• Operations push and/or pop stack values
• Exceptions: nop, wide, goto, jsr/ret
• Stack must be consistent
• Largest part of bytecode verifier
• Stack is explicitly sized per method
Wednesday, July 27, 2011
30. The JVM Stack
Depth Value
import java.lang.System
import java.io.PrintStream 0
main do
1
getstatic System, "out", PrintStream
ldc "Hello, world!"
invokevirtual PrintStream, "println",
2
[void, object]
returnvoid 3
end
4
Wednesday, July 27, 2011
31. The JVM Stack
Depth Value
import java.lang.System
import java.io.PrintStream 0 out (a PS)
main do
1
getstatic System, "out", PrintStream
ldc "Hello, world!"
invokevirtual PrintStream, "println",
2
[void, object]
returnvoid 3
end
4
Wednesday, July 27, 2011
32. The JVM Stack
Depth Value
import java.lang.System
import java.io.PrintStream 0 “Hello, world!”
main do
1 out (a PS)
getstatic System, "out", PrintStream
ldc "Hello, world!"
invokevirtual PrintStream, "println",
2
[void, object]
returnvoid 3
end
4
Wednesday, July 27, 2011
33. The JVM Stack
Depth Value
import java.lang.System
import java.io.PrintStream 0
main do
1
getstatic System, "out", PrintStream
ldc "Hello, world!"
invokevirtual PrintStream, "println",
2
[void, object]
returnvoid 3
end
4
Wednesday, July 27, 2011
34. The JVM Stack
Depth Value
import java.lang.System
import java.io.PrintStream 0
main do
1
getstatic System, "out", PrintStream
ldc "Hello, world!"
invokevirtual PrintStream, "println",
2
[void, object]
returnvoid 3
end
4
Wednesday, July 27, 2011
35. Basic Operations
• Stack manipulation
• Local variables
• Math
• Boolean
Wednesday, July 27, 2011
36. Stack Operations
0x00 nop Do nothing.
0x57 pop Discard top value from stack
0x58 pop2 Discard top two values
0x59 dup Duplicate and push top value again
0x5A dup_x1 Dup and push top value below second value
0x5B dup_x2 Dup and push top value below third value
0x5C dup2 Dup top two values and push
0x5D dup2_x1 ...below second value
0x5E dup2_x2 ...below third value
0x5F swap Swap top two values
Wednesday, July 27, 2011
37. Stack Juggling
Depth Value
dup
0 value_0
pop
swap 1 value_1
dup_x1
2
dup2_x2
3
4
Wednesday, July 27, 2011
38. Stack Juggling
Depth Value
dup
0 value_0
pop
swap 1 value_0
dup_x1
2 value_1
dup2_x2
3
4
Wednesday, July 27, 2011
39. Stack Juggling
Depth Value
dup
0 value_0
pop
swap 1 value_1
dup_x1
2
dup2_x2
3
4
Wednesday, July 27, 2011
40. Stack Juggling
Depth Value
dup
0 value_1
pop
swap 1 value_0
dup_x1
2
dup2_x2
3
4
Wednesday, July 27, 2011
41. Stack Juggling
Depth Value
dup
0 value_1
pop
swap 1 value_0
dup_x1
2 value_1
dup2_x2
3
4
Wednesday, July 27, 2011
42. Stack Juggling
Depth Value
dup
0 value_1
pop
swap 1 value_0
dup_x1
2 value_1
dup2_x2
3 value_1
4 value_0
Wednesday, July 27, 2011
43. Typed Opcodes
<type><operation>
b byte Constant values
s short Local vars (load, store)
c char
Array operations (aload, astore)
i int
Math ops (add, sub, mul, div)
l long
Boolean and bitwise
f float
d double Comparisons
a reference Conversions
Wednesday, July 27, 2011
44. Where’s boolean?
• Boolean is generally int 0 or 1
• Boolean operations push int 0 or 1
• Boolean branches expect 0 or nonzero
• To set a boolean...use int 0 or 1
Wednesday, July 27, 2011
45. Constant Values
0x01 aconst_null Push null on stack
0x02-0x08 iload_[m1-5] Push integer [-1 to 5] on stack
0x09-0x0A lconst_[0,1] Push long [0 or 1] on stack
0x0B-0x0D fconst_[0,1,2] Push float [0.0, 1.0, 2.0] on stack
0x0E-0x0F dconst_[0,1] Push double [0.0, 1.0] on stack
0x10 bipush Push byte value to stack as integer
0x11 sipush Push short value to stack as integer
0x12 ldc Push 32-bit constant to stack (int, float, string)
0x14 ldc2_w Push 64-bit constant to stack (long, double)
Wednesday, July 27, 2011
46. Why So Many?
• Reducing bytecode size
• Special iconst_0 and friends take no args
• bipush, sipush: only 8, 16 bits arguments
• Pre-optimizing JVM
• Specialized instructions can be optimized
• Doesn’t matter at all now
Wednesday, July 27, 2011
50. Woah, Two Slots?
• JVM stack slots (and local vars) are 32-bit
• 64-bit values take up two slots
• “wide” before or “w” suffix
• 64-bit field updates not atomic!
• Mind those concurrent longs/doubles!
Wednesday, July 27, 2011
54. Local Variable Table
• Local variables numbered from 0
• Instance methods have “this” at 0
• Separate table maps numbers to names
• Explicitly sized in method definition
Wednesday, July 27, 2011
55. Local Variables
0x15 iload Load integer from local variable onto stack
0x16 lload ...long...
0x17 fload ...float...
0x18 dload ...double...
0x19 aload ...reference...
0x1A-0x2D Packed loads iload_0, aload_3, etc
0x36 istore Store integer from stack into local variable
0x37 lstore ...long...
0x38 fstore ...float...
0x39 dstore ...double...
0x3A astore ...reference...
0x3B-0x4E Packed stores fstore_2, dstore_0, etc
0x84 iinc Add given amount to int local variable
Wednesday, July 27, 2011
56. Local Variables
Var Value Depth Value
ldc "hello"
0 bipush 4 0
istore 3
1 dconst_0 1
dstore 1
2 astore 0 2
aload 0
3 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
57. Local Variables
Var Value Depth Value
ldc "hello"
0 bipush 4 0 “hello”
istore 3
1 dconst_0 1
dstore 1
2 astore 0 2
aload 0
3 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
58. Local Variables
Var Value Depth Value
ldc "hello"
0 bipush 4 0 4
istore 3
1 dconst_0 1 “hello”
dstore 1
2 astore 0 2
aload 0
3 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
59. Local Variables
Var Value Depth Value
ldc "hello"
0 bipush 4 0 “hello”
istore 3
1 dconst_0 1
dstore 1
2 astore 0 2
aload 0
3 4 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
60. Local Variables
Var Value Depth Value
ldc "hello"
0 bipush 4 0
istore 3 0.0
1 dconst_0 1
dstore 1
2 astore 0 2 “hello”
aload 0
3 4 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
61. Local Variables
Var Value Depth Value
ldc "hello"
0 bipush 4 0 “hello”
istore 3
1 dconst_0 1
0.0 dstore 1
2 astore 0 2
aload 0
3 4 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
62. Local Variables
Var Value Depth Value
ldc "hello"
0 “hello” bipush 4 0
istore 3
1 dconst_0 1
0.0 dstore 1
2 astore 0 2
aload 0
3 4 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
63. Local Variables
Var Value Depth Value
ldc "hello"
0 “hello” bipush 4 0 “hello”
istore 3
1 dconst_0 1
0.0 dstore 1
2 astore 0 2
aload 0
3 4 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
64. Local Variables
Var Value Depth Value
ldc "hello"
0 “hello” bipush 4 0 “hello”
istore 3
1 dconst_0 1
0.0 dstore 1
2 astore 0 2
aload 0
3 9 iinc 3, 5
3
4 4
Wednesday, July 27, 2011
65. Arrays
0x2E-0x35 [i,l,f,d,a,b,c,d]aload Load [int, long, ...] from array (on stack) to stack
0x4F-0x56 [i,l,f,d,a,b,c,d]astore Store [int, long, ...] from stack to array (on stack)
0xBC newarray Construct new primitive array
0xBD anewarray Construct new reference array
0xBE arraylength Get array length
0xC5 multianewarray Create multi-dimensional array
Wednesday, July 27, 2011
66. Arrays
Depth Value
iconst_2
newarray int 0
dup
iconst_0 1
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
Wednesday, July 27, 2011
67. Arrays
Depth Value
iconst_2
newarray int 0 2
dup
iconst_0 1
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
Wednesday, July 27, 2011
68. Arrays
Depth Value
iconst_2
newarray int 0 int[2] {0,0}
dup
iconst_0 1
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
Wednesday, July 27, 2011
69. Arrays
Depth Value
iconst_2
newarray int 0 int[2] {0,0}
dup
iconst_0 1 int[2] {0,0}
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
Wednesday, July 27, 2011
70. Arrays
Depth Value
iconst_2
newarray int 0 0
dup
iconst_0 1 int[2] {0,0}
iconst_m1
2 int[2] {0,0}
iastore
iconst_0 3
iaload
4
5
Wednesday, July 27, 2011
71. Arrays
Depth Value
iconst_2
newarray int 0 -1
dup
iconst_0 1 0
iconst_m1
2 int[2] {0,0}
iastore
iconst_0 3 int[2] {0,0}
iaload
4
5
Wednesday, July 27, 2011
72. Arrays
Depth Value
iconst_2
newarray int 0 int[2] {-1, 0}
dup
iconst_0 1
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
Wednesday, July 27, 2011
73. Arrays
Depth Value
iconst_2
newarray int 0 0
dup
iconst_0 1 int[2] {-1, 0}
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
Wednesday, July 27, 2011
74. Arrays
Depth Value
iconst_2
newarray int 0 -1
dup
iconst_0 1
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
Wednesday, July 27, 2011
75. Math Operations
add subtract multiply divide remainder negate
+ - * / % -()
int iadd isub imul idiv irem ineg
long ladd lsub lmul ldiv lrem lneg
float fadd fsub fmul fdiv frem fneg
double dadd dsub dmul ddiv drem dneg
Wednesday, July 27, 2011
76. Boolean and Bitwise
unsigned
shift left shift right and or xor
shift right
int ishl ishr iushr iand ior ixor
Wednesday, July 27, 2011
77. Conversions
To:
int long float double byte char short
int - i2l i2f i2d i2b i2c i2s
From:
long l2i - l2f l2d - - -
float f2i f2l - f2d - - -
double d2i d2l d2f - - - -
Wednesday, July 27, 2011
78. Comparisons
0x94 lcmp Compare two longs, push int -1, 0, 1
0x95 fcmpl Compare two floats, push in -1, 0, 1 (-1 for NaN)
0x96 fcmpg Compare two floats, push in -1, 0, 1 (1 for NaN)
0x97 dcmpl Compare two doubles, push in -1, 0, 1 (-1 for NaN)
0x98 dcmpg Compare two doubles, push in -1, 0, 1 (1 for NaN)
Wednesday, July 27, 2011
79. Flow Control
• Inspect stack and branch
• Or just branch, via goto
• Labels mark branch targets
• Wide variety of tests
Wednesday, July 27, 2011
80. Flow Control
0x99 ifeq If zero on stack, branch
0x9A ifne If nonzero on stack, branch
0x9B iflt If stack value is less than zero, branch
0x9C ifge If stack value is greater than or equal to zero, branch
0x9D ifgt If stack value is greater than zero, branch
0x9E ifle If stack value is less than or equal to zero, branch
0x9F if_icmpeq If two integers on stack are eq, branch
0xA0 if_icmpne If two integers on stack are ne, branch
0xA1 if_icmplt If two integers on stack are lt, branch
0xA2 if_icmpge If two integers on stack are ge, branch
0xA3 if_icmpgt If tw
If two integers on stack are gt, branch
0xA4 if_icmple If two integers on stack are le, branch
0xA5 if_acmpeq If two references on stack are the same, branch
0xA6 if_acmpne If two references on stack are different, branch
0xA7 goto GOTO!
Wednesday, July 27, 2011
81. Other Flow Control
0xA8 jsr Jump to subroutine (deprecated)
0xA9 ret Return from subroutine (deprecated)
0xAA tableswitch Branch using an indexed table of jump offsets
0xAB lookupswitch Branch using a lookup-based table of jump offsets
0xAC-0xB0 [i,l,f,d,a]return Return (int, long, float, double, reference) value
0xB1 return Void return (exit method, return nothing)
0xC6 ifnull If reference on stack is null
0xC7 ifnonnull If reference on stack is not null
Wednesday, July 27, 2011
91. Classes and Types
• Signatures!!!
• Probably the most painful part
• ...but not a big deal if you understand
Wednesday, July 27, 2011
92. Using Classes
0xB2 getstatic Fetch static field from class
0xB3 putstatic Set static field in class
0xB4 getfield Get instance field from object
0xB5 setfield Set instance field in object
0xB6 invokevirtual Invoke instance method on object
0xB7 invokespecial Invoke constructor or “super” on object
0xB8 invokestatic Invoke static method on class
0xB9 invokeinterface Invoke interface method on object
0xBA invokedynamic Invoke method dynamically on object (Java 7)
0xBB new Construct new instance of object
0xC0 checkcast Attempt to cast object to type
0xC1 instanceof Push nonzero if object is instanceof specified type
Wednesday, July 27, 2011
93. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
an ArrayList
checkcast Collection 0 (uninitialized)
dup
ldc "first element" 1
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
94. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
an ArrayList
checkcast Collection 0 (uninitialized)
dup
an ArrayList
ldc "first element" 1 (uninitialized)
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
95. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
checkcast Collection 0 an ArrayList
dup
ldc "first element" 1
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
96. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
checkcast Collection 0 a Collection
dup
ldc "first element" 1
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
97. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
checkcast Collection 0 a Collection
dup
ldc "first element" 1 a Collection
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
98. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
“first
checkcast Collection 0 element”
dup
ldc "first element" 1 a Collection
invokeinterface Collection, 'add',
[boolean, object] 2 a Collection
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
99. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
checkcast Collection 0 1 (true)
dup
ldc "first element" 1 a Collection
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
100. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
checkcast Collection 0 a Collection
dup
ldc "first element" 1
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
101. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
checkcast Collection 0 an ArrayList
dup
ldc "first element" 1
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
102. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
checkcast Collection 0 0
dup
ldc "first element" 1 an ArrayList
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
103. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
“first
checkcast Collection 0 element”
dup
ldc "first element" 1
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
104. Using Classes
new ArrayList
dup
invokespecial ArrayList, '<init>', Depth Value
[void]
checkcast Collection 0
dup
ldc "first element" 1
invokeinterface Collection, 'add',
[boolean, object] 2
pop
checkcast ArrayList 3
ldc 0
invokevirtual ArrayList, 'get', 4
[object, int]
aprintln 5
returnvoid
Wednesday, July 27, 2011
105. Exceptions and
Synchronization
Table structure for a method indicating start/end of
- trycatch
try/catch and logic to run on exception
0xC2 monitorenter Enter synchronized block against object on stack
0xC3 monitorexit Exit synchronized block (against same object)
Wednesday, July 27, 2011
106. More Examples
• A simple loop
• Fibonacci
Wednesday, July 27, 2011
107. A Simple Loop
main do
aload 0
push_int 0
aaload
label :top
dup
aprintln
goto :top
returnvoid
end
Wednesday, July 27, 2011
111. Fibonacci
macro :load_times do
aload 0
ldc 0
aaload # number of times
invokestatic JInteger, 'parseInt',
[int, string]
end
Wednesday, July 27, 2011
112. Fibonacci
macro :start_timing do |i|
load_time
lstore i
end
Wednesday, July 27, 2011
113. Fibonacci
macro :load_time do
invokestatic System, "currentTimeMillis", long
end
Wednesday, July 27, 2011
114. Fibonacci
macro :end_timing do |i|
load_time
lload i
lsub
lstore i
end
Wednesday, July 27, 2011
115. Fibonacci
macro :lprintln do |i|
getstatic System, "out", PrintStream
lload i
invokevirtual PrintStream, "println",
[void, long]
end
Wednesday, July 27, 2011
116. ASM
• “All purpose bytecode manipulation and
analysis framework.”
• De facto standard bytecode library
• http://asm.ow2.org
Wednesday, July 27, 2011
117. Basic Process
• Construct a ClassWriter
• Visit structure
• Annotations, methods, fields, inner classes
• Write out bytes
Wednesday, July 27, 2011
118. Blah.java
public class Blah implements Cloneable {
private final String fieldName;
public Blah() {
fieldName = "hello";
}
public static Blah makeBlah() {
return new Blah();
}
}
Wednesday, July 27, 2011
119. ClassWriter
ClassWriter cv = new ClassWriter(
ClassWriter.COMPUTE_MAXS |
ClassWriter.COMPUTE_FRAMES);
Wednesday, July 27, 2011
120. COMPUTE...what?
• COMPUTE_MAXS
• ASM will calculate max stack/local vars
• COMPUTE_FRAMES
• ASM will calculate Java 6 stack map
• Hints to verifier that we’ve pre-validated
stack contents (sort of)
Wednesday, July 27, 2011
121. Visit Class
cv.visit(
Opcodes.V1_6,
Opcodes.ACC_PUBLIC,
"Blah",
null,
"java/lang/Object",
new String[] {"java/lang/Cloneable"});
Wednesday, July 27, 2011
122. Opcodes
• Interface full of constants
• Bytecodes
• Visibility modifiers
• Java versions
• Other stuff
Wednesday, July 27, 2011
123. ACC_*
• Some you know
• ACC_PUBLIC, ACC_ABSTRACT, etc
• Some you don’t
• ACC_BRIDGE, ACC_SYNTHETIC
Wednesday, July 27, 2011
124. Java Version
• V1_1 through V1_7
• Sorry 1.0!
Wednesday, July 27, 2011
125. Class Names
"java/lang/Object"
packageClass.replaceAll('.', '/')
Wednesday, July 27, 2011
137. ASMifierClassVisitor
• Dump ASM visitor calls from .class file
• Very raw, but very useful
Wednesday, July 27, 2011
138. Blah.java
public class Blah implements Cloneable {
private final String fieldName;
public Blah() {
fieldName = "hello";
}
public static Blah makeBlah() {
return new Blah();
}
}
Wednesday, July 27, 2011
140. Real-world Cases
• Reflection-free invocation
• JRuby, Groovy, other languages
• Bytecoded data objects
• Hibernate, other data layers
• java.lang.reflect.Proxy and others
• Language compilers
Wednesday, July 27, 2011
142. JIT
• Just-In-Time compilation
• Compiled when needed
• Maybe immediately before execution
• ...or when we decide it’s important
• ...or never?
Wednesday, July 27, 2011
144. Profiling
• Gather data about code while interpreting
• Invariants (types, constants, nulls)
• Statistics (branches, calls)
• Use that information to optimize
• Educated guess?
Wednesday, July 27, 2011
146. The Golden Rule
of Optimization
Don’t do unnecessary work.
Wednesday, July 27, 2011
147. Perf Sinks
• Memory accesses
• By far the biggest expense
• Calls
• Opaque memory ref + branch
• Locks, volatile writes
• Kills multi-cpu perf
Wednesday, July 27, 2011
148. Volatile?
• Each CPU maintains a memory cache
• Caches may be out of sync
• If it doesn’t matter, no problem
• If it does matter, threads disagree!
• Volatile forces synchronization of cache
• Across cores and to main memory
Wednesday, July 27, 2011
149. Inlining?
• Combine caller and callee into one unit
• e.g. based on profile
• Perhaps with a sanity check
• Optimize as a whole
Wednesday, July 27, 2011
150. Inlining
int addAll(int max) {
int accum = 0;
for (int i = 0; i < max; i++) {
accum = add(accum, i);
}
return accum;
}
int add(int a, int b) {
return a + b;
}
Wednesday, July 27, 2011
151. Inlining
int addAll(int max) {
int accum = 0;
for (int i = 0; i < max; i++) {
accum = add(accum, i);
}
return accum;
} Only one target is ever seen
int add(int a, int b) {
return a + b;
}
Wednesday, July 27, 2011
152. Inlining
int addAll(int max) {
int accum = 0;
for (int i = 0; i < max; i++) {
accum = accum + i;
}
return accum;
} Don’t bother making a call
Wednesday, July 27, 2011
153. Call Site
• The place where you make a call
• Monomorphic (“one shape”)
• Single target class
• Bimorphic (“two shapes”)
• Polymorphic (“many shapes”)
• Megamorphic (“you’re screwed”)
Wednesday, July 27, 2011
154. Blah.java
System.currentTimeMillis(); // static, monomorphic
List list1 = new ArrayList(); // constructor, monomorphic
List list2 = new LinkedList();
for (List list : new List[]{ list1, list2 }) {
list.add("hello"); // bimorphic
}
for (Object obj : new Object[]{ 'foo', list1, new Object() }) {
obj.toString(); // polymorphic
}
Wednesday, July 27, 2011
155. Hotspot
• -client mode (C1) inlines, less aggressive
• Fewer opportunities to optimize
• -server mode (C2) profiles, inlines
• We’ll focus on this
• Tiered mode combines them
• -XX:+TieredCompilation
Wednesday, July 27, 2011
156. Hotspot Inlining
• Profile to find “hot spots”
• Largely focused around call sites
• Profile until 10k calls
• Inline mono/bimorphic calls
• Other mechanisms for polymorphic calls
Wednesday, July 27, 2011
158. Monitoring the JIT
• Dozens of flags
• PrintCompilation
• PrintInlining
• LogCompilation
• PrintAssembly
• Some in product, some in debug...
Wednesday, July 27, 2011
159. public class Accumulator {
public static void main(String[] args) {
int max = Integer.parseInt(args[0]);
System.out.println(addAll(max));
}
static int addAll(int max) {
int accum = 0;
for (int i = 0; i < max; i++) {
accum = add(accum, i);
}
return accum;
}
static int add(int a, int b) {
return a + b;
}
}
Wednesday, July 27, 2011
160. ~/oscon ➔ java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-b00)
OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode)
~/oscon ➔ javac Accumulator.java
~/oscon ➔ java Accumulator 1000
499500
Wednesday, July 27, 2011
161. PrintCompilation
• -XX:+PrintCompilation
• Print methods as they are jitted
• Class + name + size
Wednesday, July 27, 2011
168. What if you see this...
~/oscon ➔ java -client -XX:+PrintCompilation Accumulator 1000
1 java.lang.String::hashCode (64 bytes)
2 java.math.BigInteger::mulAdd (81 bytes)
3 java.math.BigInteger::multiplyToLen (219 bytes)
4 java.math.BigInteger::addOne (77 bytes)
5 java.math.BigInteger::squareToLen (172 bytes)
5 made not entrant java.math.BigInteger::squareToLen (172 bytes)
7 java.math.BigInteger::montReduce (99 bytes)
6 java.math.BigInteger::primitiveLeftShift (79 bytes)
8 java.math.BigInteger::squareToLen (172 bytes)
9 sun.security.provider.SHA::implCompress (491 bytes)
10 java.lang.String::charAt (33 bytes)
499500
Wednesday, July 27, 2011
169. Optimistic Compiler
• Assume profile is accurate
• Aggressively optimize based on profile
• Bail out if we’re wrong
• And hope that we’re usually right
Wednesday, July 27, 2011
170. Deoptimization
• Bail out of running code
• Monitoring flags describe process
• “uncommon trap” - we were wrong
• “not entrant” - don’t let anyone enter
• “zombie” - on its way to deadness
Wednesday, July 27, 2011
171. What if you see this...
20 java.math.BigInteger::addOne (77 bytes)
21 java.math.BigInteger::squareToLen (172 bytes)
22 java.math.BigInteger::primitiveLeftShift (79 bytes)
--- n java.lang.System::arraycopy (static)
24 sun.security.provider.SHA::implCompress (491 bytes)
23 java.math.BigInteger::montReduce (99 bytes)
25 java.lang.String$CaseInsensitiveComparator::compare (115
bytes)
26 java.lang.Character::toLowerCase (162 bytes)
Wednesday, July 27, 2011
172. What if you see this...
20 java.math.BigInteger::addOne (77 bytes)
21 java.math.BigInteger::squareToLen (172 bytes)
22 java.math.BigInteger::primitiveLeftShift (79 bytes)
--- n java.lang.System::arraycopy (static)
24 sun.security.provider.SHA::implCompress (491 bytes)
23 java.math.BigInteger::montReduce (99 bytes)
25 java.lang.String$CaseInsensitiveComparator::compare (115
bytes)
26 java.lang.Character::toLowerCase (162 bytes)
Native calls don’t compile, may be
intrinsic. We’ll come back to that.
Wednesday, July 27, 2011
173. PrintInlining
• -XX:+UnlockDiagnosticVMOptions
-XX:+PrintInlining
• Display hierarchy of inlined methods
• Include reasons for not inlining
• More, better output on OpenJDK 7
Wednesday, July 27, 2011
175. ~/oscon ➔ java -XX:+UnlockDiagnosticVMOptions
> -XX:+PrintInlining
> Accumulator 10000
49995000
Um...I don’t see anything inlining...
Wednesday, July 27, 2011
176. public class Accumulator {
public static void main(String[] args) {
int max = Integer.parseInt(args[0]);
System.out.println(addAll(max));
}
Called once
static int addAll(int max) {
int accum = 0;
for (int i = 0; i < max; i++) {
accum = add(accum, i);
}
return accum; Called 10k times...
}
static int add(int a, int b) {
return a + b;
} ...but no calls to inline!
}
Wednesday, July 27, 2011