9.
‣What Can We Learn From Them?
• Complied code is faster than interpreted code
• It’s very hard (almost impossible) to ﬁgure things out staticly
• The type proﬁle of a program is stable over time
• Therefore:
• Learn what a program does and optimize based on that
• This is called Type Feedback
Wednesday, September 16, 2009

11.
‣Type Proﬁle
• As the program executes, it’s possible to see how one method
calls another methods
• The relationship of one method and all the methods it calls is the
type proﬁle of the method
• Just because you CAN use dynamic dispatch, doesn’t mean you
always do.
• It’s common that a call site always calls the same method every
time it’s run
Wednesday, September 16, 2009

15.
‣Method Inlining
• Rather than emit a call to a target method, copy it’s body at the
call site
• Eliminates code to lookup and begin execution of target method
• Simpliﬁes (or eliminates) setup for target method
• Allows for type propagation, as well as providing a wider horizon
for optimization.
• A wider horizon means better generated code, which means
less work to do per method == faster execution.
Wednesday, September 16, 2009

19.
‣Type Proﬁling
• All call sites use a class called InlineCache, one per call site
• InlineCache accelerates method dispatch by caching previous
method used
• In addition, tracks a ﬁxed number of receiver classes seen when
there is a cache miss
• When compiling a method using LLVM, all InlineCaches for a
method can be read
• InlineCaches with good information can be used to accurately
ﬁnd a method to inline
Wednesday, September 16, 2009

20.
‣When To Compile
• It takes time for a method’s type information to settle down
• Compiling too early means not having enough type info
• Compiling too late means lost performance
• Use simple call counters to allow a method to “heat up”
• Each invocation of a method increments counter
• When counter reaches a certain value, method is queued for
compilation.
• Threshold value is tunable: -Xjit.call_til_compile
• Still experimenting with good default values
Wednesday, September 16, 2009

21.
‣How to Compile
• To impact runtime as little as possible, all JIT compilation happens
in a background OS thread
• Methods are queued, and background thread reads queue to ﬁnd
methods to compile
• After compiling, function pointers to JIT generated code are
installed in methods
• All future invocations of method use JIT code
Wednesday, September 16, 2009

26.
‣Conclusion
• Ruby is a wonderful language because it is organized for humans
• By gather and using information about a running program, it’s
possible to make that program much faster without impacting
ﬂexibility
• Thank You!
Wednesday, September 16, 2009