SlideShare une entreprise Scribd logo
1  sur  65
Télécharger pour lire hors ligne
JRuby 9000
Optimizing Above the JVM
Me
• Charles Oliver Nutter (@headius)
• Red Hat
• Based in Minneapolis, Minnesota
• Ten years working on JRuby (uff da!)
Ruby Challenges
• Dynamic dispatch for most things
• Dynamic possibly-mutating constants
• Fixnum to Bignum promotion
• Literals for arrays, hashes: [a, b, c].sort[1]
• Stack access via closures, bindings
• Rich inheritance model
module SayHello

def say_hello

"Hello, " + to_s

end

end



class Foo

include SayHello



def initialize

@my_data = {bar: 'baz', quux: 'widget'}

end



def to_s

@my_data.map do |k,v|

"#{k} = #{v}"

end.join(', ')

end

end



Foo.new.say_hello # => "Hello, bar = baz, quux = widget"
More Challenges
• "Everything's an object"
• Tracing and debugging APIs
• Pervasive use of closures
• Mutable literal strings
JRuby 9000
• Mixed mode runtime (now with tiers!)
• Lazy JIT to JVM bytecode
• byte[] strings and regular expressions
• Lots of native integration via FFI
• 9.0.5.0 is current
New IR
• Optimizable intermediate representation
• AST to semantic IR
• Traditional compiler design
• Register machine
• SSA-ish where it's useful
Lexical
Analysis
Parsing
Semantic
Analysis
Optimization
Bytecode
Generation
Interpret
AST
IR Instructions
CFG DFG ...
JRuby 1.7.x
9000+
Bytecode
Generation
Interpret
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
2 b = recv_pre_reqd_arg(1)
3 %block = recv_closure
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Register-based
3 address format
IR InstructionsSemantic
Analysis
-Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
2 b = recv_pre_reqd_arg(1)
3 %block = recv_closure
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization
-Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
2 b = recv_pre_reqd_arg(1)
3 %block = recv_closure
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization
-Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
2 b = recv_pre_reqd_arg(1)
3 %block = recv_closure
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
6 c =
7 line_num(2)
8 %v_0 = call(:+, a, [ ])
9 d = copy(%v_0)
10 return(%v_0)
1
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
7 line_num(2)
8 %v_0 = call(:+, a, [1])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
7 line_num(2)
8 %v_0 = call(:+, a, [1])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
7 line_num(2)
8 %v_0 = call(:+, a, [1])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
Tiers in the Rain
• Tier 1: Simple interpreter (no passes run)
• Tier 2: Full interpreter (static optimization)
• Tier 3: Full interpreter (profiled optz)
• Tier 4: JVM bytecode (static)
• Tier 5: JVM bytecode (profiled)
• Tiers 6+:Whatever JVM does from there
Truffle?
• Write your AST + specializations
• AST rewrites as it runs
• Eventually emits Graal IR (i.e. not JVM)
• Very fast peak perf on benchmarks
• Poor startup, warmup, memory use
• Year(s) left until generally usable
Red/black tree benchmark
0
2.25
4.5
6.75
9
JRuby int JRuby no indy JRuby with indy
JRuby+Truffle CRuby 2.3
Why Not Just JVM?
• JVM is great, but missing many things
• I'll mention some along the way
Current Optimizations
Block Jitting
• JRuby 1.7 only jitted methods
• Not free-standing procs/lambdas
• Not define_method blocks
• Easier to do now with 9000's IR
• Blocks JIT as of 9.0.4.0
define_method
Convenient for metaprogramming,
but blocks have more overhead than methods.
define_method(:add) do |a, b|

a + b

end
names.each do |name|

define_method(name) { send :"do_#{name}" }

end
Optimizing define_method
• Noncapturing
• Treat as method in compiler
• Ignore surrounding scope
• Capturing (future work)
• Lift read-only variables as constant
Getting Better!
0k iters/s
1000k iters/s
2000k iters/s
3000k iters/s
4000k iters/s
def define_method define_method w/ capture
MRI JRuby 9.0.1.0 JRuby 9.0.4.0
JVM?
• Missing feature: access to call frames
• No way to expose local variables
• Therefore, have to use heap
• Allocation, loss of locality
Low-cost Exceptions
• Backtrace cost isVERY high on JVM
• Lots of work to construct
• Exceptions frequently ignored
• ...or used as flow control (shame!)
• If ignored, backtrace is not needed!
Postfix Antipattern
foo rescue nil
Exception raised
StandardError rescued
Exception ignored
Result is simple expression, so exception is never visible.
csv.rb Converters
Converters = { integer: lambda { |f|

Integer(f) rescue f

},

float: lambda { |f|

Float(f) rescue f

},

...
All trivial rescues, no traces needed.
Strategy
• Inspect rescue block
• If simple expression...
• Thread-local requiresBacktrace = false
• Backtrace generation short circuited
• Reset to true on exit or nontrivial rescue
Simple rescue
Improvement
0
150000
300000
450000
600000
Iters/second
524,475
10,700
Much Better!
1
10
100
1000
10000
100000
1000000
Iters/second
524,475
10,700
JVM?
• Horrific cost for stack traces
• Only eliminated if inlined
• Disabling is not really an option
Work In Progress
Object Shaping
• Ruby instance vars allocated dynamically
• JRuby currently grows an array
• We have code to specialize as fields
• Working, tested
• Probably next release
public class RubyObjectVar2 extends ReifiedRubyObject {

private Object var0;

private Object var1;

private Object var2;

public RubyObjectVar2(Ruby runtime, RubyClass metaClass) {

super(runtime, metaClass);

}



@Override

public Object getVariable(int i) {

switch (i) {

case 0: return var0;

case 1: return var1;

case 2: return var2;

default: return super.getVariable(i);

}

}



public Object getVariable0() {

return var0;

}

...


public void setVariable0(Object value) {

ensureInstanceVariablesSettable();

var0 = value;

}
...


}
JVM?
• No way to truly generify fields
• Valhalla will be useful here
• No way to grow an object
Inlining
• 900 pound gorilla of optimization
• shove method/closure back to callsite
• specialize closure-receiving methods
• eliminate call protocol
• We know Ruby better than the JVM
JVM?
• JVM will inline for us, but...
• only if we use invokedynamic
• and the code isn't too big
• and it's not polymorphic
• and we're not a closure (lambdas too!)
• and it feels like it
Today’s Inliner
def decrement_one(i)
i - 1
end
i = 1_000_000
while i > 0
i = decrement_one(i)
end
def decrement_one(i)
i - 1
end
i = 1_000_000
while i < 0
if guard_same? self
i = i - 1
else
i = decrement_one(i)
end
end
Today’s Inliner
def decrement_one(i)
i - 1
end
i = 1_000_000
while i > 0
i = decrement_one(i)
end
def decrement_one(i)
i - 1
end
i = 1_000_000
while i < 0
if guard_same? self
i = i - 1
else
i = decrement_one(i)
end
end
Today’s Inliner
def decrement_one(i)
i - 1
end
i = 1_000_000
while i > 0
i = decrement_one(i)
end
def decrement_one(i)
i - 1
end
i = 1_000_000
while i < 0
if guard_same? self
i = i - 1
else
i = decrement_one(i)
end
end
Today’s Inliner
def decrement_one(i)
i - 1
end
i = 1_000_000
while i > 0
i = decrement_one(i)
end
def decrement_one(i)
i - 1
end
i = 1_000_000
while i < 0
if guard_same? self
i = i - 1
else
i = decrement_one(i)
end
end
Profiling
• You can't inline if you can't profile!
• For each call site record call info
• Which method(s) called
• How frequently
• Inline most frequently-called method
Inlining a Closure
def small_loop(i)
k = 10
while k > 0
k = yield(k)
end
i - 1
end
def big_loop(i)
i = 100_000
while true
i = small_loop(i) { |j| j - 1 }
return 0 if i < 0
end
end
900.times { |i| big_loop i }
hot & monomorphic
Like an Array#each
May see many blocks
JVM will not inline this
Inlining FTW!
0
15
30
45
60
Time in seconds
14.1
56.9
Profiling
• <2% overhead (to be reduced more)
• Working* (interpreter AND JIT)
• Feeds directly into inlining
• Deopt coming soon
* Fragile and buggy!
Interpreter FTW!
• Deopt is much simpler with interpreter
• Collect local vars, instruction index
• Raise exception to interpreter, keep going
• Much cheaper than resuming bytecode
Numeric Specialization
• "Unboxing"
• Ruby: everything's an object
• Tagged pointer for Fixnum, Float
• JVM: references OR primitives
• Need to optimize numerics as primitive
JVM?
• Escape analysis is inadequate (today)
• Hotspot will eliminate boxes if...
• All code inlines
• No (unfollowed?) branches in the code
• Dynamic calls have type guards
• Fixnum + Fixnum has overflow check
def looper(n)

i = 0

while i < n

do_something(i)

i += 1

end

end
def looper(long n)

long i = 0

while i < n

do_something(i)

i += 1

end

end
Specialize n, i to long
def looper(n)

i = 0

while i < n

do_something(i)

i += 1

end

end
Deopt to object version if n or i + 1 is not Fixnum
Unboxing Today
• Working prototype
• No deopt
• No type guards
• No overflow check for Fixnum/Bignum
Rendering
*
*
*
*
*
***
*****
*****
***
*
*********
*************
***************
*********************
*********************
*******************
*******************
*******************
*******************
***********************
*******************
*******************
*********************
*******************
*******************
*****************
***************
*************
*********
*
***************
***********************
* ************************* *
*****************************
* ******************************* *
*********************************
***********************************
***************************************
*** ***************************************** ***
*************************************************
***********************************************
*********************************************
*********************************************
***********************************************
***********************************************
***************************************************
*************************************************
*************************************************
***************************************************
***************************************************
* *************************************************** *
***** *************************************************** *****
****** *************************************************** ******
******* *************************************************** *******
***********************************************************************
********* *************************************************** *********
****** *************************************************** ******
***** *************************************************** *****
***************************************************
***************************************************
***************************************************
***************************************************
*************************************************
*************************************************
***************************************************
***********************************************
***********************************************
*******************************************
*****************************************
*********************************************
**** ****************** ****************** ****
*** **************** **************** ***
* ************** ************** *
*********** ***********
** ***** ***** **
* * * *
0.520000 0.020000 0.540000 ( 0.388744)
def iterate(x,y)

cr = y-0.5

ci = x

zi = 0.0

zr = 0.0

i = 0

bailout = 16.0

max_iterations = 1000



while true

i += 1

temp = zr * zi

zr2 = zr * zr

zi2 = zi * zi

zr = zr2 - zi2 + cr

zi = temp + temp + ci

return i if (zi2 + zr2 > bailout)

return 0 if (i > max_iterations)

end

end
Mandelbrot performance
0
0.075
0.15
0.225
0.3
JRuby JRuby + truffle
Mandelbrot performance
0
0.075
0.15
0.225
0.3
JRuby JRuby + truffle JRuby on Graal
Mandelbrot performance
0
0.035
0.07
0.105
0.14
JRuby + truffle JRuby on Graal JRuby unbox
When?
• Object shape should be in 9.1
• Profiling, inlining mostly need testing
• Specialization needs guards, deopt
• Active work over next 6-12mo
Summary
• JVM is great, but we need more
• Partial EA, frame access, specialization
• Gotta stay ahead of these youngsters!
• JRuby 9000 is aVM on top of aVM
• We believe we can match Truffle
• (for a large range of optimizations)
ThankYou
• Charles Oliver Nutter
• @headius
• headius@headius.com

Contenu connexe

Tendances

これからのPerlプロダクトのかたち(YAPC::Asia 2013)
これからのPerlプロダクトのかたち(YAPC::Asia 2013)これからのPerlプロダクトのかたち(YAPC::Asia 2013)
これからのPerlプロダクトのかたち(YAPC::Asia 2013)
goccy
 
JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013
Vladimir Ivanov
 
Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012
Anton Arhipov
 
2008 07-24 kwpm-threads_and_synchronization
2008 07-24 kwpm-threads_and_synchronization2008 07-24 kwpm-threads_and_synchronization
2008 07-24 kwpm-threads_and_synchronization
fangjiafu
 

Tendances (20)

JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
 
Down the Rabbit Hole
Down the Rabbit HoleDown the Rabbit Hole
Down the Rabbit Hole
 
これからのPerlプロダクトのかたち(YAPC::Asia 2013)
これからのPerlプロダクトのかたち(YAPC::Asia 2013)これからのPerlプロダクトのかたち(YAPC::Asia 2013)
これからのPerlプロダクトのかたち(YAPC::Asia 2013)
 
Ruby 2.4 Internals
Ruby 2.4 InternalsRuby 2.4 Internals
Ruby 2.4 Internals
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder Ruby
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013
 
Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012
 
Why scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisWhy scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with this
 
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
 
Java & low latency applications
Java & low latency applicationsJava & low latency applications
Java & low latency applications
 
Concurrency in Python
Concurrency in PythonConcurrency in Python
Concurrency in Python
 
RubyKaigi2015 making robots-with-mruby
RubyKaigi2015 making robots-with-mrubyRubyKaigi2015 making robots-with-mruby
RubyKaigi2015 making robots-with-mruby
 
Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++
 
Clojure in real life 17.10.2014
Clojure in real life 17.10.2014Clojure in real life 17.10.2014
Clojure in real life 17.10.2014
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?
 
Asynchronous I/O in Python 3
Asynchronous I/O in Python 3Asynchronous I/O in Python 3
Asynchronous I/O in Python 3
 
2008 07-24 kwpm-threads_and_synchronization
2008 07-24 kwpm-threads_and_synchronization2008 07-24 kwpm-threads_and_synchronization
2008 07-24 kwpm-threads_and_synchronization
 

En vedette

Codes and conventions of a music magazine contents
Codes and conventions of a music magazine contentsCodes and conventions of a music magazine contents
Codes and conventions of a music magazine contents
Ellie Niccolls
 
CommunicationFundamentals_CertificateOfCompletion (1)
CommunicationFundamentals_CertificateOfCompletion (1)CommunicationFundamentals_CertificateOfCompletion (1)
CommunicationFundamentals_CertificateOfCompletion (1)
Susan Smith
 
ntv linked in
ntv linked inntv linked in
ntv linked in
noel ver
 

En vedette (13)

Save the date MBA REFRESHER
Save the date MBA REFRESHERSave the date MBA REFRESHER
Save the date MBA REFRESHER
 
Codes and conventions of a music magazine contents
Codes and conventions of a music magazine contentsCodes and conventions of a music magazine contents
Codes and conventions of a music magazine contents
 
Final Draft HTM 4964
Final Draft HTM 4964Final Draft HTM 4964
Final Draft HTM 4964
 
CommunicationFundamentals_CertificateOfCompletion (1)
CommunicationFundamentals_CertificateOfCompletion (1)CommunicationFundamentals_CertificateOfCompletion (1)
CommunicationFundamentals_CertificateOfCompletion (1)
 
E-Biz Marketing Plan
E-Biz Marketing PlanE-Biz Marketing Plan
E-Biz Marketing Plan
 
ntv linked in
ntv linked inntv linked in
ntv linked in
 
What's in a Name?
What's in a Name?What's in a Name?
What's in a Name?
 
Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)
 
5 Simple Ways to keep your Heart Healthy!
5 Simple Ways to keep your Heart Healthy!5 Simple Ways to keep your Heart Healthy!
5 Simple Ways to keep your Heart Healthy!
 
War of deodorants
War of deodorantsWar of deodorants
War of deodorants
 
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...
 
Motivación
MotivaciónMotivación
Motivación
 
Exámenes de docentes2
Exámenes de docentes2Exámenes de docentes2
Exámenes de docentes2
 

Similaire à JRuby 9000 - Optimizing Above the JVM

JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
Charles Nutter
 
Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010
Dirkjan Bussink
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
Lin Yo-An
 
Invoke dynamic your api to hotspot
Invoke dynamic your api to hotspotInvoke dynamic your api to hotspot
Invoke dynamic your api to hotspot
Boundary
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
Stefan Marr
 

Similaire à JRuby 9000 - Optimizing Above the JVM (20)

There and Back Again
There and Back AgainThere and Back Again
There and Back Again
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
 
Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010
 
Rubinius 1.0 and more!
Rubinius 1.0 and more!Rubinius 1.0 and more!
Rubinius 1.0 and more!
 
Ruby is an Acceptable Lisp
Ruby is an Acceptable LispRuby is an Acceptable Lisp
Ruby is an Acceptable Lisp
 
Python高级编程(二)
Python高级编程(二)Python高级编程(二)
Python高级编程(二)
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPH
 
MacRuby, an introduction
MacRuby, an introductionMacRuby, an introduction
MacRuby, an introduction
 
Jvm memory model
Jvm memory modelJvm memory model
Jvm memory model
 
Run Node Run
Run Node RunRun Node Run
Run Node Run
 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentation
 
Appsec obfuscator reloaded
Appsec obfuscator reloadedAppsec obfuscator reloaded
Appsec obfuscator reloaded
 
Code lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf LinzCode lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf Linz
 
Functional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks weekFunctional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks week
 
Why MacRuby Matters
Why MacRuby MattersWhy MacRuby Matters
Why MacRuby Matters
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
 
Invoke dynamic your api to hotspot
Invoke dynamic your api to hotspotInvoke dynamic your api to hotspot
Invoke dynamic your api to hotspot
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
 
Some Rough Fibrous Material
Some Rough Fibrous MaterialSome Rough Fibrous Material
Some Rough Fibrous Material
 
New features in Ruby 2.5
New features in Ruby 2.5New features in Ruby 2.5
New features in Ruby 2.5
 

Plus de Charles Nutter

High Performance Ruby - Golden Gate RubyConf 2012
High Performance Ruby - Golden Gate RubyConf 2012High Performance Ruby - Golden Gate RubyConf 2012
High Performance Ruby - Golden Gate RubyConf 2012
Charles Nutter
 

Plus de Charles Nutter (18)

Open Source Software Needs You!
Open Source Software Needs You!Open Source Software Needs You!
Open Source Software Needs You!
 
InvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesInvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method Handles
 
Over 9000: JRuby in 2015
Over 9000: JRuby in 2015Over 9000: JRuby in 2015
Over 9000: JRuby in 2015
 
Doing Open Source the Right Way
Doing Open Source the Right WayDoing Open Source the Right Way
Doing Open Source the Right Way
 
JRuby: The Hard Parts
JRuby: The Hard PartsJRuby: The Hard Parts
JRuby: The Hard Parts
 
Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014
 
Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013
 
Invokedynamic in 45 Minutes
Invokedynamic in 45 MinutesInvokedynamic in 45 Minutes
Invokedynamic in 45 Minutes
 
Invokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesInvokedynamic: Tales from the Trenches
Invokedynamic: Tales from the Trenches
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012
 
Aloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyAloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRuby
 
High Performance Ruby - Golden Gate RubyConf 2012
High Performance Ruby - Golden Gate RubyConf 2012High Performance Ruby - Golden Gate RubyConf 2012
High Performance Ruby - Golden Gate RubyConf 2012
 
Euruko 2012 - JRuby
Euruko 2012 - JRubyEuruko 2012 - JRuby
Euruko 2012 - JRuby
 
InvokeDynamic - You Ain't Seen Nothin Yet
InvokeDynamic - You Ain't Seen Nothin YetInvokeDynamic - You Ain't Seen Nothin Yet
InvokeDynamic - You Ain't Seen Nothin Yet
 
Building Languages for the JVM - StarTechConf 2011
Building Languages for the JVM - StarTechConf 2011Building Languages for the JVM - StarTechConf 2011
Building Languages for the JVM - StarTechConf 2011
 
JRuby: What's Different (RORO Melbourne October 2011)
JRuby: What's Different (RORO Melbourne October 2011)JRuby: What's Different (RORO Melbourne October 2011)
JRuby: What's Different (RORO Melbourne October 2011)
 

Dernier

The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Dernier (20)

Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 

JRuby 9000 - Optimizing Above the JVM

  • 2. Me • Charles Oliver Nutter (@headius) • Red Hat • Based in Minneapolis, Minnesota • Ten years working on JRuby (uff da!)
  • 3. Ruby Challenges • Dynamic dispatch for most things • Dynamic possibly-mutating constants • Fixnum to Bignum promotion • Literals for arrays, hashes: [a, b, c].sort[1] • Stack access via closures, bindings • Rich inheritance model
  • 4. module SayHello
 def say_hello
 "Hello, " + to_s
 end
 end
 
 class Foo
 include SayHello
 
 def initialize
 @my_data = {bar: 'baz', quux: 'widget'}
 end
 
 def to_s
 @my_data.map do |k,v|
 "#{k} = #{v}"
 end.join(', ')
 end
 end
 
 Foo.new.say_hello # => "Hello, bar = baz, quux = widget"
  • 5. More Challenges • "Everything's an object" • Tracing and debugging APIs • Pervasive use of closures • Mutable literal strings
  • 6. JRuby 9000 • Mixed mode runtime (now with tiers!) • Lazy JIT to JVM bytecode • byte[] strings and regular expressions • Lots of native integration via FFI • 9.0.5.0 is current
  • 7. New IR • Optimizable intermediate representation • AST to semantic IR • Traditional compiler design • Register machine • SSA-ish where it's useful
  • 9. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 2 b = recv_pre_reqd_arg(1) 3 %block = recv_closure 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Register-based 3 address format IR InstructionsSemantic Analysis
  • 10. -Xir.passes=LocalOptimizationPass, DeadCodeElimination def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 2 b = recv_pre_reqd_arg(1) 3 %block = recv_closure 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization
  • 11. -Xir.passes=LocalOptimizationPass, DeadCodeElimination def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 2 b = recv_pre_reqd_arg(1) 3 %block = recv_closure 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization
  • 12. -Xir.passes=LocalOptimizationPass, DeadCodeElimination def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 2 b = recv_pre_reqd_arg(1) 3 %block = recv_closure 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization
  • 13. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 14. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 15. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 16. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 6 c = 7 line_num(2) 8 %v_0 = call(:+, a, [ ]) 9 d = copy(%v_0) 10 return(%v_0) 1 Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 17. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 7 line_num(2) 8 %v_0 = call(:+, a, [1]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 18. 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 7 line_num(2) 8 %v_0 = call(:+, a, [1]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 19. 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 7 line_num(2) 8 %v_0 = call(:+, a, [1]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 20. Tiers in the Rain • Tier 1: Simple interpreter (no passes run) • Tier 2: Full interpreter (static optimization) • Tier 3: Full interpreter (profiled optz) • Tier 4: JVM bytecode (static) • Tier 5: JVM bytecode (profiled) • Tiers 6+:Whatever JVM does from there
  • 21. Truffle? • Write your AST + specializations • AST rewrites as it runs • Eventually emits Graal IR (i.e. not JVM) • Very fast peak perf on benchmarks • Poor startup, warmup, memory use • Year(s) left until generally usable
  • 22. Red/black tree benchmark 0 2.25 4.5 6.75 9 JRuby int JRuby no indy JRuby with indy JRuby+Truffle CRuby 2.3
  • 23. Why Not Just JVM? • JVM is great, but missing many things • I'll mention some along the way
  • 25. Block Jitting • JRuby 1.7 only jitted methods • Not free-standing procs/lambdas • Not define_method blocks • Easier to do now with 9000's IR • Blocks JIT as of 9.0.4.0
  • 26. define_method Convenient for metaprogramming, but blocks have more overhead than methods. define_method(:add) do |a, b|
 a + b
 end names.each do |name|
 define_method(name) { send :"do_#{name}" }
 end
  • 27. Optimizing define_method • Noncapturing • Treat as method in compiler • Ignore surrounding scope • Capturing (future work) • Lift read-only variables as constant
  • 28. Getting Better! 0k iters/s 1000k iters/s 2000k iters/s 3000k iters/s 4000k iters/s def define_method define_method w/ capture MRI JRuby 9.0.1.0 JRuby 9.0.4.0
  • 29. JVM? • Missing feature: access to call frames • No way to expose local variables • Therefore, have to use heap • Allocation, loss of locality
  • 30. Low-cost Exceptions • Backtrace cost isVERY high on JVM • Lots of work to construct • Exceptions frequently ignored • ...or used as flow control (shame!) • If ignored, backtrace is not needed!
  • 31. Postfix Antipattern foo rescue nil Exception raised StandardError rescued Exception ignored Result is simple expression, so exception is never visible.
  • 32. csv.rb Converters Converters = { integer: lambda { |f|
 Integer(f) rescue f
 },
 float: lambda { |f|
 Float(f) rescue f
 },
 ... All trivial rescues, no traces needed.
  • 33. Strategy • Inspect rescue block • If simple expression... • Thread-local requiresBacktrace = false • Backtrace generation short circuited • Reset to true on exit or nontrivial rescue
  • 36. JVM? • Horrific cost for stack traces • Only eliminated if inlined • Disabling is not really an option
  • 38. Object Shaping • Ruby instance vars allocated dynamically • JRuby currently grows an array • We have code to specialize as fields • Working, tested • Probably next release
  • 39. public class RubyObjectVar2 extends ReifiedRubyObject {
 private Object var0;
 private Object var1;
 private Object var2;
 public RubyObjectVar2(Ruby runtime, RubyClass metaClass) {
 super(runtime, metaClass);
 }
 
 @Override
 public Object getVariable(int i) {
 switch (i) {
 case 0: return var0;
 case 1: return var1;
 case 2: return var2;
 default: return super.getVariable(i);
 }
 }
 
 public Object getVariable0() {
 return var0;
 }
 ... 
 public void setVariable0(Object value) {
 ensureInstanceVariablesSettable();
 var0 = value;
 } ... 
 }
  • 40. JVM? • No way to truly generify fields • Valhalla will be useful here • No way to grow an object
  • 41. Inlining • 900 pound gorilla of optimization • shove method/closure back to callsite • specialize closure-receiving methods • eliminate call protocol • We know Ruby better than the JVM
  • 42. JVM? • JVM will inline for us, but... • only if we use invokedynamic • and the code isn't too big • and it's not polymorphic • and we're not a closure (lambdas too!) • and it feels like it
  • 43. Today’s Inliner def decrement_one(i) i - 1 end i = 1_000_000 while i > 0 i = decrement_one(i) end def decrement_one(i) i - 1 end i = 1_000_000 while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) end end
  • 44. Today’s Inliner def decrement_one(i) i - 1 end i = 1_000_000 while i > 0 i = decrement_one(i) end def decrement_one(i) i - 1 end i = 1_000_000 while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) end end
  • 45. Today’s Inliner def decrement_one(i) i - 1 end i = 1_000_000 while i > 0 i = decrement_one(i) end def decrement_one(i) i - 1 end i = 1_000_000 while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) end end
  • 46. Today’s Inliner def decrement_one(i) i - 1 end i = 1_000_000 while i > 0 i = decrement_one(i) end def decrement_one(i) i - 1 end i = 1_000_000 while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) end end
  • 47. Profiling • You can't inline if you can't profile! • For each call site record call info • Which method(s) called • How frequently • Inline most frequently-called method
  • 48. Inlining a Closure def small_loop(i) k = 10 while k > 0 k = yield(k) end i - 1 end def big_loop(i) i = 100_000 while true i = small_loop(i) { |j| j - 1 } return 0 if i < 0 end end 900.times { |i| big_loop i } hot & monomorphic Like an Array#each May see many blocks JVM will not inline this
  • 50. Profiling • <2% overhead (to be reduced more) • Working* (interpreter AND JIT) • Feeds directly into inlining • Deopt coming soon * Fragile and buggy!
  • 51. Interpreter FTW! • Deopt is much simpler with interpreter • Collect local vars, instruction index • Raise exception to interpreter, keep going • Much cheaper than resuming bytecode
  • 52. Numeric Specialization • "Unboxing" • Ruby: everything's an object • Tagged pointer for Fixnum, Float • JVM: references OR primitives • Need to optimize numerics as primitive
  • 53. JVM? • Escape analysis is inadequate (today) • Hotspot will eliminate boxes if... • All code inlines • No (unfollowed?) branches in the code • Dynamic calls have type guards • Fixnum + Fixnum has overflow check
  • 54. def looper(n)
 i = 0
 while i < n
 do_something(i)
 i += 1
 end
 end def looper(long n)
 long i = 0
 while i < n
 do_something(i)
 i += 1
 end
 end Specialize n, i to long def looper(n)
 i = 0
 while i < n
 do_something(i)
 i += 1
 end
 end Deopt to object version if n or i + 1 is not Fixnum
  • 55. Unboxing Today • Working prototype • No deopt • No type guards • No overflow check for Fixnum/Bignum
  • 56. Rendering * * * * * *** ***** ***** *** * ********* ************* *************** ********************* ********************* ******************* ******************* ******************* ******************* *********************** ******************* ******************* ********************* ******************* ******************* ***************** *************** ************* ********* * *************** *********************** * ************************* * ***************************** * ******************************* * ********************************* *********************************** *************************************** *** ***************************************** *** ************************************************* *********************************************** ********************************************* ********************************************* *********************************************** *********************************************** *************************************************** ************************************************* ************************************************* *************************************************** *************************************************** * *************************************************** * ***** *************************************************** ***** ****** *************************************************** ****** ******* *************************************************** ******* *********************************************************************** ********* *************************************************** ********* ****** *************************************************** ****** ***** *************************************************** ***** *************************************************** *************************************************** *************************************************** *************************************************** ************************************************* ************************************************* *************************************************** *********************************************** *********************************************** ******************************************* ***************************************** ********************************************* **** ****************** ****************** **** *** **************** **************** *** * ************** ************** * *********** *********** ** ***** ***** ** * * * * 0.520000 0.020000 0.540000 ( 0.388744)
  • 57. def iterate(x,y)
 cr = y-0.5
 ci = x
 zi = 0.0
 zr = 0.0
 i = 0
 bailout = 16.0
 max_iterations = 1000
 
 while true
 i += 1
 temp = zr * zi
 zr2 = zr * zr
 zi2 = zi * zi
 zr = zr2 - zi2 + cr
 zi = temp + temp + ci
 return i if (zi2 + zr2 > bailout)
 return 0 if (i > max_iterations)
 end
 end
  • 58.
  • 59.
  • 62. Mandelbrot performance 0 0.035 0.07 0.105 0.14 JRuby + truffle JRuby on Graal JRuby unbox
  • 63. When? • Object shape should be in 9.1 • Profiling, inlining mostly need testing • Specialization needs guards, deopt • Active work over next 6-12mo
  • 64. Summary • JVM is great, but we need more • Partial EA, frame access, specialization • Gotta stay ahead of these youngsters! • JRuby 9000 is aVM on top of aVM • We believe we can match Truffle • (for a large range of optimizations)
  • 65. ThankYou • Charles Oliver Nutter • @headius • headius@headius.com