16. def foo
bar
end
def bar
baz
end
def baz
# ...
end
foo bar baz
JRuby
call
logic
JRuby
call
logic
Stops many JVM optimizations
JRuby before invokedynamic
JRuby
call
logic
19. def foo
bar
end
def bar
baz
end
def baz
# ...
end
foo bar baz
JRuby
call
logic
JRuby
call
logic
Stops many JVM optimizations
JRuby before invokedynamic
JRuby
call
logic
21. "In the future, we will consider bounded extensions to the Java Virtual
Machine to provide better support for other languages."
- JVM Specification First Edition (1997), preface
22. Goals of
InvokeDynamic
• A new bytecode
• Fast function pointers + adapters
• Caching and invalidation
• Flexible enough for future uses
27. invokestatic
1. Confirm arguments are of correct type
2. Look up method on Java class
3. Cache method
4. Invoke method
invokevirtual
1. Confirm object is of correct type
2. Confirm arguments are of correct type
3. Look up method on Java class
4. Cache method
5. Invoke method
invokeinterface
1. Confirm object’s type implements interface
2. Confirm arguments are of correct type
3. Look up method on Java class
4. Cache method
5. Invoke method
invokespecial
1. Confirm object is of correct type
2. Confirm arguments are of correct type
3. Confirm target method is visible
4. Look up method on Java class
5. Cache method
6. Invoke method
invokedynamic
1. Call your language's logic
2. Install target function
3.Target function invoked directly until you change it
36. // can access everything visible from here
MethodHandles.Lookup LOOKUP =
MethodHandles.lookup();
// can access only public fields and methods
MethodHandles.Lookup PUBLOOKUP =
MethodHandles.publicLookup();
42. // insert is like partial application
MethodHandle getJavaHomeMH =
MethodHandles.insertArguments(getPropertyMH, 0, "java.home");
// same as getProperty("java.home")
getJavaHomeMH.invokeWithArguments();
48. Bootstrap
• First time JVM sees invokedynamic
• Call your bootstrap code with name, type
• Install resulting CallSite
• Subsequent times
• Just invoke call site contents
49. CallSite
• Holds a MethodHandle
• Returned to JVM by bootstrap method
• Replaces invokedynamic bytecode
• JVM watches it for changes
50. public static CallSite simpleBootstrap(
MethodHandles.Lookup lookup,
String name,
MethodType type) throws Exception {
// Create and bind a constant site, pointing at the named method
return new ConstantCallSite(
lookup.findStatic(SimpleBinding.class, name, type));
}
60. def foo
bar
end
def bar
baz
end
def baz
# ...
end
foo bar baz
JRuby
call
logic
JRuby
call
logic
Stops many JVM optimizations
JRuby before invokedynamic
JRuby
call
logic
61. def foo
bar
end
def bar
baz
end
def baz
# ...
end
foo bar baz
JRuby
call
logic
JRuby
call
logic
Dynamic call logic built into JVM
JRuby on Java 7
JRuby
call
logic
X X
66. Empty Method Call
10M calls to empty method
0.32
0.328
0.335
0.343
0.35
Time in seconds
67. Lazy Constants
• Call site just produces a value
• Value calculated once
• Subsequent access is direct, optimizable
• Used for numbers, strings, regexp
72. Constant Lookup
Look up "Foo" constant 10m times
0
0.3
0.6
0.9
1.2
Time in seconds
MRI JRuby Control
73. InstanceVariables
• Ruby objects grow as needed
• Look up offset for @var in object
• Cache offset, guard against other types
• Direct access to variable table