This document provides an introduction to JVM bytecode, including how to inspect, generate, and understand bytecode. It discusses two main parts - JVM bytecode itself such as basic instructions and stack operations, and the JVM JIT compiler which compiles bytecode to machine code. Various tools for working with bytecode like javap and ASM are also introduced. The document is intended to help readers gain a better understanding of how the Java platform works from the lowest level.
Introduction to JVM bytecode concept, its inspection and generation. Speaker details and session context are provided.
Definition and characteristics of JVM bytecode including one-byte instructions, opcodes, and an example of a simple Hello World program in Java. Usage of `javap` for disassembling Java class files to display class structure and bytecode with detailed examples.
Introduction to `TraceClassVisitor` and `ASMifierClassVisitor` tools for inspecting and generating bytecode, along with BiteScript for emitting JVM bytecode.
Discussion of `BiteScript`, an internal DSL for JVM, and installations and applications of users working with JVM bytecode.
Basics of JVM bytecode including stack operations, flow control, and examples of stack manipulation through bitecode.
Overview of basic bytecode operations like stack manipulation, local variables, constant values, and the reasoning for extensive opcode types.
Detailed structure and operations concerning arrays in JVM bytecode. Examples show array creation and manipulation.
Mathematical and boolean operations in JVM bytecode, including add, subtract, multiply, and logical operations.
Control flow mechanisms including branching, labels, and various condition checks with examples in bytecode.
Handling classes and method invocation in JVM bytecode, showing how to interact with collections and object methods.
Introduction to the invokedynamic feature introduced in Java 7 and the use of MethodHandles to dynamically bind method calls.
Overview of exception handling, synchronization constructs, and the structure needed to manage exceptions in JVM.
Examples of simple loops, Fibonacci calculations, using macros for operational efficiencies in bytecode creation.
General applications of JVM bytecode in various languages, and a look into tooling available for developers.
Intro
• Charles OliverNutter
• “JRuby Guy”
• Sun Microsystems 2006-2009
• Engine Yard 2009-
• Primarily responsible for compiler, perf
• Lots of bytecode generation
3.
Two Parts
• JVM Bytecode
• Inspection
• Generation
• How it works
• JVM JIT
• How it works
• Monitoring
• Assembly (don’t be scared!)
4.
Two Parts
}
• JVM Bytecode
• Inspection
Today
• Generation
• How it works
}
• JVM JIT
• How it works Session 25141
Hilton Yosemite ABC
• Monitoring
Wednesday 10AM
• Assembly (don’t be scared!)
5.
Bytecode Definition
• “...instruction sets designed for efficient
execution by a software interpreter ...”
• “... suitable for further compilation into
machine code.
6.
Byte Code
• One-byteinstructions
• 256 possible “opcodes”
• 200 in use on current JVMs
• Room for more :-)
• Little variation since Java 1.0
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
9.
Hello World
public classHelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world");
}
}
javap
~/projects/bytecode_for_dummies ➔ javapHelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld extends java.lang.Object{
public HelloWorld();
public static void main(java.lang.String[]);
}
12.
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
}
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
}
28.
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
29.
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
30.
BiteScript
main do
ldc "Hello, world!"
aprintln
returnvoid A BiteScript “macro”
end
31.
BiteScript
macro :aprintln do
getstatic System, "out", PrintStream
swap
invokevirtual PrintStream, "println",
[void, object]
end
32.
The Basics
• Stackmachine
• Basic operations
• Flow control
• Class structures
• Exception handling
33.
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
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
35.
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
36.
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
37.
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
38.
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
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
41.
Stack Juggling
Depth Value
dup
0 value_0
pop
swap 1 value_1
dup_x1
2
dup2_x2
3
4
42.
Stack Juggling
Depth Value
dup
0 value_0
pop
swap 1 value_0
dup_x1
2 value_1
dup2_x2
3
4
43.
Stack Juggling
Depth Value
dup
0 value_0
pop
swap 1 value_1
dup_x1
2
dup2_x2
3
4
44.
Stack Juggling
Depth Value
dup
0 value_1
pop
swap 1 value_0
dup_x1
2
dup2_x2
3
4
45.
Stack Juggling
Depth Value
dup
0 value_1
pop
swap 1 value_0
dup_x1
2 value_1
dup2_x2
3
4
46.
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
47.
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
48.
Where’s boolean?
• Booleanis 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
49.
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)
50.
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
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!
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
59.
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
60.
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
61.
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
62.
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
63.
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
64.
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
65.
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
66.
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
67.
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
68.
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
69.
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
70.
Arrays
Depth Value
iconst_2
newarray int 0
dup
iconst_0 1
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
71.
Arrays
Depth Value
iconst_2
newarray int 0 2
dup
iconst_0 1
iconst_m1
2
iastore
iconst_0 3
iaload
4
5
72.
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
Boolean and Bitwise
unsigned
shift left shift right and or xor
shift right
int ishl ishr iushr iand ior ixor
81.
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 - - - -
82.
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)
83.
Flow Control
• Inspectstack and branch
• Or just branch, via goto
• Labels mark branch targets
• Wide variety of tests
84.
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!
85.
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
Classes and Types
•Signatures!!!
• Probably the most painful part
• ...but not a big deal if you understand
96.
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
97.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
98.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
99.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
100.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
101.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
102.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
103.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
104.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
105.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
106.
Using Classes
new ArrayList
dup
invokespecialArrayList, '<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
Emitting Invokedynamic
• Signatureis still required
• But can be almost anything
• Method name is still required
• But can be almost anything
• MethodHandle for bootstrapping
• Bytecode-level function pointer, basically
111.
java.lang.invoke
• MethodHandles
• Function points
• Adapters (arg juggling, catch, conditionals)
• CallSites
• Place to bind your MH chain
• SwitchPoint
• Zero-cost volatile boolean branch
Target Method
# Themethod we want to invoke, prints given string
public_static_method :print, [], void, string do
aload 0
aprintln
returnvoid
end
114.
Invokedynamic
# Our mainmethod, which does one invokedynamic
main do
# handle for our bootstrap, which binds invokedynamic to a CallSite
bootstrap = mh_invokestatic this, 'bootstrap',
CallSite, Lookup, string, MethodType
ldc 'Hello, invokedynamic!'
invokedynamic 'print', [void, string], bootstrap
returnvoid
end
115.
Invokedynamic
# Our mainmethod, which does one invokedynamic
main do
# handle for our bootstrap, which binds invokedynamic to a CallSite
bootstrap = mh_invokestatic this, 'bootstrap',
CallSite, Lookup, string, MethodType
ldc 'Hello, invokedynamic!'
invokedynamic 'print', [void, string], bootstrap
returnvoid
end
116.
Invokedynamic
# Our mainmethod, which does one invokedynamic
main do
# handle for our bootstrap, which binds invokedynamic to a CallSite
bootstrap = mh_invokestatic this, 'bootstrap',
CallSite, Lookup, string, MethodType
ldc 'Hello, invokedynamic!'
invokedynamic 'print', [void, string], bootstrap
returnvoid
end
117.
Invokedynamic
# Our mainmethod, which does one invokedynamic
main do
# handle for our bootstrap, which binds invokedynamic to a CallSite
bootstrap = mh_invokestatic this, 'bootstrap',
CallSite, Lookup, string, MethodType
ldc 'Hello, invokedynamic!'
invokedynamic 'print', [void, string], bootstrap
returnvoid
end
118.
Bootstrap
# The bootstrapmethod, which binds our dynamic call
public_static_method :bootstrap, [], CallSite,
Lookup, string, MethodType do
# Constant since we bind just once directly
new ConstantCallSite
dup
# Locate the method indicated by name + type on current class
aload 0 # Lookup
ldc this # this class
aload 1 # String
aload 2 # MethodType
invokevirtual Lookup, 'findStatic',
[MethodHandle, JClass, string, MethodType]
# finish constructing call site and return
invokespecial ConstantCallSite, '<init>', [void, MethodHandle]
areturn
end
119.
Bootstrap
# The bootstrapmethod, which binds our dynamic call
public_static_method :bootstrap, [], CallSite,
Lookup, string, MethodType do
# Constant since we bind just once directly
new ConstantCallSite
dup
# Locate the method indicated by name + type on current class
aload 0 # Lookup
ldc this # this class
aload 1 # String
aload 2 # MethodType
invokevirtual Lookup, 'findStatic',
[MethodHandle, JClass, string, MethodType]
# finish constructing call site and return
invokespecial ConstantCallSite, '<init>', [void, MethodHandle]
areturn
end
120.
Bootstrap
# The bootstrapmethod, which binds our dynamic call
public_static_method :bootstrap, [], CallSite,
Lookup, string, MethodType do
# Constant since we bind just once directly
new ConstantCallSite
dup
# Locate the method indicated by name + type on current class
aload 0 # Lookup
ldc this # this class
aload 1 # String
aload 2 # MethodType
invokevirtual Lookup, 'findStatic',
[MethodHandle, JClass, string, MethodType]
# finish constructing call site and return
invokespecial ConstantCallSite, '<init>', [void, MethodHandle]
areturn
end
121.
Bootstrap
# The bootstrapmethod, which binds our dynamic call
public_static_method :bootstrap, [], CallSite,
Lookup, string, MethodType do
# Constant since we bind just once directly
new ConstantCallSite
dup
# Locate the method indicated by name + type on current class
aload 0 # Lookup
ldc this # this class
aload 1 # String
aload 2 # MethodType
invokevirtual Lookup, 'findStatic',
[MethodHandle, JClass, string, MethodType]
# finish constructing call site and return
invokespecial ConstantCallSite, '<init>', [void, MethodHandle]
areturn
end
122.
Bootstrap
# The bootstrapmethod, which binds our dynamic call
public_static_method :bootstrap, [], CallSite,
Lookup, string, MethodType do
# Constant since we bind just once directly
new ConstantCallSite
dup
# Locate the method indicated by name + type on current class
aload 0 # Lookup
ldc this # this class
aload 1 # String
aload 2 # MethodType
invokevirtual Lookup, 'findStatic',
[MethodHandle, JClass, string, MethodType]
# finish constructing call site and return
invokespecial ConstantCallSite, '<init>', [void, MethodHandle]
areturn
end
123.
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)
Fibonacci
macro :lprintln do|i|
getstatic System, "out", PrintStream
lload i
invokevirtual PrintStream, "println",
[void, long]
end
134.
Real-world Cases
• Reflection-freeinvocation
• JRuby, Groovy, other languages
• Bytecoded data objects
• Hibernate, other data layers
• java.lang.reflect.Proxy and others
• Language compilers
135.
Tools
• BiteScript
•So much fun
• Ruby, so that’s even better
• JiteScript
• ASM - defacto standard library
136.
Part 2 Topics
• Tracking your bytecode • Dumping JVM JIT
through the JVM assembly output
• How the JVM optimizes • x86 assembler language
running code for dummies!
• Monitoring JVM JIT
compilation
• Inspecting JVM inlining
137.
Pluggity
• Many thanksto Engine Yard
• JRuby and Java PaaS
• JRuby support and services
• sales@engineyard.com