SlideShare une entreprise Scribd logo
1  sur  71
Télécharger pour lire hors ligne
The Hard Parts
Subverting the JVM
All the tricks, hacks, and kludges we’ve use to make	

JRuby the best off-JVM language impl around.
Intro
• Charles Oliver Nutter	

• Principal Software Engineer	

• Red Hat, JBoss Polyglot Group	

• @headius	

• headius@headius.com
Welcome!
• My favorite event of the year	

• I’ve only missed one!	

• I will quickly talk through JRuby challenges	

• Not a comprehensive list. Buy me a beer.	

• Rest of you can help solve them
Ruby
• Dynamic, object-oriented language	

• Created in 90s byYukihiro Matsumoto	

• “matz”	

• Matz’s Ruby Interpreter (MRI)	

• Inspired by Python, Perl, Lisp, Smalltalk	

• Memes:TMTOWTDI, MINASWAN, CoC,
# Output "I love Ruby"!
say = "I love Ruby"!
puts say!
!
# Output "I *LOVE* RUBY"!
say['love'] = "*love*"!
puts say.upcase!
!
# Output "I *love* Ruby"!
# five times!
5.times { puts say }!
JRuby
• Ruby for the JVM and JVM for the Ruby	

• Started in 2001, dozens of contribs	

• Usually the fastest Ruby	

• At least 20 paid full-time man years in it	

• Sun Microsystems, EngineYard, Red Hat
Ruby is Hard to	

Implement!
Making It Go (Fast)
• Parser-generator hacks	

• Multiple interpreters	

• Multiple compilers	

• JVM-specific tricks
Parsing Ruby
• Yacc/Bison-based parse.y, almost 12kloc	

• Very complex, not context-free	

• No known 100% correct parser that is
notYACC-based
JRuby’s Parser
• Jay parser generator	

• Maybe 5 projects in the world use it	

• Our version of parse.y = 4kloc	

• Two pieces, one is for offline parsing	

• Works ok, but…
Parser Problems!
• Array initialization > 65k bytecode	

• Giant switch won’t JIT	

• Outlining the case bodies: better	

• Case bodies as runnables in machine: best	

• org/jruby/parser/RubyParser$445.class	

• Slow at startup (most important time!)
Interpreter
• At least four interpreters we’ve tried	

• Original: visitor-based	

• Modified: big switch rather than visitor	

• Experimental: stackless instr-based	

• Current: direct execution of AST	

• Execution state on artificial stack
The New Way
• JRuby 9000 introduces a new IR	

• Traditional-style compiler IR	

• Register-based	

• CFG, semantic analysis, type and constant
propagation, all that jazz	

• Interpreter has proven it out…JIT next
Mixed-Mode
• JRuby has both interpreter and JIT	

• Cost of generating JVM bytecode is high	

• Our interpreter runs faster than JVM’s	

• A jitted interpreter is (much) faster than
unjitted bytecode
Native Execution
• Early JIT compiler just translated AST	

• Bare-minimum semantic analysis	

• Eliminate artificial frame use	

• One-off opto for frequent patterns	

• Too unwieldy to evolve much
New IR JIT
• Builds off IR runtime	

• Per-instruction bytecode gen is simple	

• JVM frame is like infinite register machine	

• Potential to massively improve perf	

• Early unboxing numbers…
Numeric loop performance
0
1.25
2.5
3.75
5
times faster than MRI 2.1
JRuby 1.7 Rubinius
Numeric loop performance
0
15
30
45
60
times faster than MRI 2.1
JRuby 1.7 Rubinius Truffle Topaz 9k+unbox
mandelbrot(500)
0
10
20
30
40
times faster than MRI 2.1
JRuby 9k + indy JRuby 9k + unboxing JRuby 9k + Truffle
Whither Truffle?
• RubyTruffle merged into JRuby	

• Same licenses as rest of JRuby	

• Chris Seaton continues to work on it	

• Very impressive peak numbers	

• Startup, steady-state…needs work	

• Considering initial use for targeted opto
JVM Tricks
• Lack of class hierarchy analysis in JIT	

• Manually split methods to beat limits	

• Everything is an expression, so exception-
handling has to maintain current stack	

• Tweaking JIT flags will just make you sad	

• Unsafe
IRubyObject
public RubyClass getMetaClass();
RubyBasicObject
private RubyClass metaClass;	

public RubyClass getMetaClass() {	

return metaClass;	

}
RubyString RubyArray RubyObject
obj.getMetaClass()
public static RubyClass metaclass(IRubyObject object) {

return object instanceof RubyBasicObject ?

((RubyBasicObject)object).getMetaClass() :

object.getMetaClass();

}
Compatibility
• Strings and Encodings	

• IO	

• Fibers	

• Difficult choices
Strings
• All arbitrary-width byte data is String	

• Binary data and encoded text alike	

• Many supported encodings	

• j.l.String, char[] poor options	

• Size, data integrity, behavioral differences
The First Big Decision
• We realized we needed a byte[] String	

• Had been StringBuilder-based until then	

• That meant a lot of porting…	

• Regex engine (joni)	

• Encoding subsystem (jcodings)	

• Low-level IO + transcoding (in JRuby)
JOni
• Port of Oniguruma regex library	

• Pluggable grammars + arbitrary encodings	

• Bytecode engine (shallow call stack)	

• Interruptible	

• Re-forked as char[] engine for Nashorn	

• https://github.com/jruby/joni
Data:‘a’-‘z’ in byte[]	

Match /.*tuv(..)yz$/
0s
1.5s
3s
4.5s
6s
j.u.regex JOni
Data:‘a’-‘z’ from IO	

Match /.*tuv(..)yz$/
0s
0.7s
1.4s
2.1s
2.8s
j.u.regex JOni
Jcodings
• Character tables	

• Used heavily by JOni and JRuby	

• Transcoding tables and logic	

• Replaces Charset logic from JRuby 1.7	

• https://github.com/jruby/jcodings
NO GRAPH NEEDED
JRuby 9000
• Finished porting, connecting transcoders	

• New port of IO operations	

• Transcoding works directly against IO
buffers; hard to simulate other ways	

• Lots of fun native (C) calls to emulate…
Fibers
• Coroutines, goroutines, continuations	

• MRI uses stack-swapping	

• And limits Fiber stack size as a result	

• Useless as a concurrency model	

• Useful for multiplexing operations	

• Try read, no data, go to next fiber
Fibers on JRuby
• Yep, they’re just native threads	

• Transfer perf with j.u.c utils is pretty close	

• Resource load is very bad	

• Spin-up time is bad without thread pool	

• So early or occasional fibers cost a lot	

• Where are you, coro?!
Hard Decisions
• ObjectSpace walks heap, off by default	

• Trace functions add overhead, off by default	

• Full coroutines not possible	

• C extension API too difficult to emulate	

• Perhaps only item to really hurt us
Native Integration
• Process control	

• More selectable IO	

• FFI layer	

• C extension API	

• Misc
Ruby’s Roots
• Matz is/was a C programmer	

• Early Ruby did little more than stitch C
calls together	

• Some of those roots remain	

• ttys, fcntl, process control, IO, ext API	

• We knew we needed a solution
JNA, and then JNR
• Started with jna-posix to map POSIX	

• stat, symlink, etc needed to do basics	

• JNR replaced JNA	

• Wayne Meissner started his empire…
The Cancer
• Many off-platform runtimes are not as good
as Hotspot	

• Many of their users must turn to C for perf	

• So, since many people use C exts on MRI,
maybe we need to implement it?	

• Or get a student to do it…
MRI C Extensions
• Very invasive API	

• Direct pointer access, object internals,
conservative GC, threading constraints	

• Like bridging one JNI to another	

• Experimental in JRuby 1.6, gone in 1.7	

• Will not revisit unless new API
FFI
• Ruby API/DSL for binding C libs	

• Additional tools for generating that code	

• If you need to go native, it’s the best way	

• In use in production JRuby apps	

• ØMQ client, bson lib, sodium crypto, …
Ruby FFI example
class Timeval < FFI::Struct!
  layout :tv_sec => :ulong,!
:tv_usec => :ulong!
end!
!
module LibC!
  extend FFI::Library!
  ffi_lib FFI::Library::LIBC!
  attach_function :gettimeofday,!
[ :pointer, :pointer ],!
:int!
end!
!
t = Timeval.new!
LibC.gettimeofday(t.pointer, nil)
Layered Runtime
jffi
jnr-ffi
libffi
jnr-posix	

jnr-constants
!
jnr-enxio
jnr-x86asm
jnr-unixsocket
etc etc
Native in JRuby
• POSIX stuff missing from Java	

• Ruby FFI DSL for binding C libs	

• Stdio	

• selection, remove buffering, control tty	

• Process launching and control	

• !!!!!!
Process Control
• Java’s ProcessBuilder/Process are bad	

• No channel access (no select!)	

• Spins up at least one thread per process	

• Drains child output ahead of you	

• New process API based on posix_spawn
in_c, in_p = IO.pipe
out_p, out_c = IO.pipe
!
pid = spawn('cat -n',
:in => in_c,
:out => out_c,
:err => 'error.log')
!
[in_c, out_c].each(&:close)
!
in_p.puts("hello, world")
in_p.close
!
puts out_p.read # => " 1 hello, world"
!
Process.waitpid(pid)
Usability
• Backtraces	

• Command-line and launchers	

• Startup time
Backtraces
• JVM backtraces make Rubyists’ eyes bleed	

• Initially, Ruby trace maintained manually	

• JIT emits mangled class to produce a Ruby
trace element	

• AOT produces single class, mangled
method name	

• Mixed-mode backtraces!
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1061)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:910)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892)
at groovy.lang.Closure.call(Closure.java:279)
at
org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMet
hods.java:1911)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:
1184)
at org.codehaus.groovy.runtime.dgm$88.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite
$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:270)
at
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:
124)
at BootStrap.populateBootstrapData(BootStrap.groovy:786)
at BootStrap.this$2$populateBootstrapData(BootStrap.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1061)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:910)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1009)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:910)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892)
at
at org.jruby.javasupport.JavaMethod.invokeStaticDirect(JavaMethod.java:362)	

	

 at org.jruby.java.invokers.StaticMethodInvoker.call(StaticMethodInvoker.java:50)	

	

 at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)	

	

 at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)	

	

 at org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60)	

	

 at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)	

	

 at org.jruby.ast.RootNode.interpret(RootNode.java:129)	

	

 at org.jruby.evaluator.ASTInterpreter.INTERPRET_EVAL(ASTInterpreter.java:95)	

	

 at org.jruby.evaluator.ASTInterpreter.evalWithBinding(ASTInterpreter.java:184)	

	

 at org.jruby.RubyKernel.evalCommon(RubyKernel.java:1158)	

	

 at org.jruby.RubyKernel.eval19(RubyKernel.java:1121)	

	

 at org.jruby.RubyKernel$INVOKER$s$0$3$eval19.call(RubyKernel$INVOKER$s$0$3$eval19.gen)	

	

 at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:210)	

	

 at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:206)	

	

 at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:599)	

	

 at org.jruby.runtime.invokedynamic.InvocationLinker.invocationFallback(InvocationLinker.java:155)	

	

 at ruby.__dash_e__.method__1$RUBY$bar(-e:1)	

	

 at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:599)	

	

 at org.jruby.runtime.invokedynamic.InvocationLinker.invocationFallback(InvocationLinker.java:138)	

	

 at ruby.__dash_e__.block_0$RUBY$foo(-e:1)	

	

 at ruby$__dash_e__$block_0$RUBY$foo.call(ruby$__dash_e__$block_0$RUBY$foo)	

	

 at org.jruby.runtime.CompiledBlock19.yieldSpecificInternal(CompiledBlock19.java:117)	

	

 at org.jruby.runtime.CompiledBlock19.yieldSpecific(CompiledBlock19.java:92)	

	

 at org.jruby.runtime.Block.yieldSpecific(Block.java:111)	

	

 at org.jruby.RubyFixnum.times(RubyFixnum.java:275)	

	

 at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:599)	

	

 at org.jruby.runtime.invokedynamic.InvocationLinker.invocationFallback(InvocationLinker.java:230)	

	

 at ruby.__dash_e__.method__0$RUBY$foo(-e:1)	

	

 at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:599)	

	

 at org.jruby.runtime.invokedynamic.InvocationLinker.invocationFallback(InvocationLinker.java:138)	

	

 at ruby.__dash_e__.__file__(-e:1)
• org.jruby.RubyFixnum.times	

• org.jruby.evaluator.ASTInterpreter.INTERPRET_EVAL	

• rubyjit.Object$
$foo_3AB1F5052668B3CD74A0B4CD4999CF6A65E9
2973271627940.__file__	

• ruby.__dash_e__.method__0$RUBY$foo
Command Line
• Rubyists typically are at CLI	

• Command line and tty must behave	

• Epic bash and .bat scripts	

• 300-500 lines of heinous shell script	

• Unusable in shebang lines	

• Repurposed NetBeans native launcher
system ~/projects/jruby $ time bin/jruby.bash -v	
jruby 9000.dev-SNAPSHOT (2.1.2) 2014-07-27 9cca1ec Java HotSpot(TM) 64-Bit Server VM 24.45-b08 on
1.7.0_45-b18 [darwin-x86_64]	
!
real	0m0.126s	
user	0m0.092s	
sys	 0m0.031s	
!
system ~/projects/jruby $ time bin/jruby.bash -v	
jruby 9000.dev-SNAPSHOT (2.1.2) 2014-07-27 9cca1ec Java HotSpot(TM) 64-Bit Server VM 24.45-b08 on
1.7.0_45-b18 [darwin-x86_64]	
!
real	0m0.124s	
user	0m0.089s	
sys	 0m0.033s	
!
system ~/projects/jruby $ time jruby -v	
jruby 9000.dev-SNAPSHOT (2.1.2) 2014-07-27 9cca1ec Java HotSpot(TM) 64-Bit Server VM 24.45-b08 on
1.7.0_45-b18 [darwin-x86_64]	
!
real	0m0.106s	
user	0m0.080s	
sys	 0m0.022s	
!
system ~/projects/jruby $ time jruby -v	
jruby 9000.dev-SNAPSHOT (2.1.2) 2014-07-27 9cca1ec Java HotSpot(TM) 64-Bit Server VM 24.45-b08 on
1.7.0_45-b18 [darwin-x86_64]	
!
real	0m0.110s	
user	0m0.085s	
sys	 0m0.023s
Console Support
• Rubyists also typically use REPLs	

• Readline support is a must	

• jline has been forked all over the place	

• Looking into JNA-based readline now
CLI == Startup Time
• BY FAR the #1 complaint	

• May be the only reason we haven’t won!	

• We’re trying everything we can
JRuby Startup
-e 1
gem --help
rake -T
Time in seconds (lower is better)
0 2.5 5 7.5 10
C Ruby JRuby
Tweaking Flags
• -client mode	

• -XX:+TieredCompilation -XX:TieredStopAtLevel=1	

• -X-C to disable JRuby’s compiler	

• Heap sizes, code verification, etc etc
Nailgun?
• Keep a single JVM running in background	

• Toss commands over to it	

• It stays hot, so code starts faster	

• Hard to clean up all state (e.g. threads)	

• Can’t get access to user’s terminal	

• http://www.martiansoftware.com/nailgun/
Drip
Isolated JVM
ApplicationCommand #1
Isolated JVM
ApplicationCommand #1
Isolated JVM
ApplicationCommand #1
Drip
• Start a new JVM after each command	

• Pre-boot JVM plus optional code	

• Analyze command line for differences	

• Age out unused instances	

• https://github.com/flatland/drip
Drip Init
• Give Drip some code to pre-boot	

• Load more libraries	

• Warm up some code	

• Pre-execution initialization	

• Run as much as possible in background	

• We also pre-load ./dripmain.rb if exists
$ cat dripmain.rb	
# Preload some code Rails always needs	
require File.expand_path('../config/application', __FILE__)
JRuby Startup
rake -T
Time in seconds (lower is better)
0 2.5 5 7.5 10
C Ruby JRuby JRuby (best)
JRuby (drip) JRuby (drip init) JRuby (dripmain)
CONCLUSION
Hard Parts
• 64k bytecode limit	

• Falling over JIT limits	

• String char[] pain	

• Startup and warmup 	

• Coroutines	

• FFI at JVM level	

• Too many flags	

• Tiered compiler slow	

• Interpreter opto	

• Bytecode is a blunt tool	

• Indy has taken too long	

• Charlie may burn out
ThankYou!
• Charles Oliver Nutter	

• @headius	

• headius@headius.com	

• http://blog.headius.com

Contenu connexe

Tendances

Charles nutter star techconf 2011 - jvm languages
Charles nutter   star techconf 2011 - jvm languagesCharles nutter   star techconf 2011 - jvm languages
Charles nutter star techconf 2011 - jvm languagesStarTech Conference
 
Java tuning on GNU/Linux for busy dev
Java tuning on GNU/Linux for busy devJava tuning on GNU/Linux for busy dev
Java tuning on GNU/Linux for busy devTomek Borek
 
Building MapAttack
Building MapAttackBuilding MapAttack
Building MapAttackKyle Drake
 
JRuby - The Best of Java and Ruby
JRuby - The Best of Java and RubyJRuby - The Best of Java and Ruby
JRuby - The Best of Java and RubyEvgeny Rahman
 
An introduction and future of Ruby coverage library
An introduction and future of Ruby coverage libraryAn introduction and future of Ruby coverage library
An introduction and future of Ruby coverage librarymametter
 
Expert JavaScript Programming
Expert JavaScript ProgrammingExpert JavaScript Programming
Expert JavaScript ProgrammingYoshiki Shibukawa
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013Charles Nutter
 
Modern Java Concurrency (Devoxx Nov/2011)
Modern Java Concurrency (Devoxx Nov/2011)Modern Java Concurrency (Devoxx Nov/2011)
Modern Java Concurrency (Devoxx Nov/2011)Martijn Verburg
 
Rails development environment talk
Rails development environment talkRails development environment talk
Rails development environment talkReuven Lerner
 
Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threadsmperham
 
Fast, concurrent ruby web applications with EventMachine and EM::Synchrony
Fast, concurrent ruby web applications with EventMachine and EM::SynchronyFast, concurrent ruby web applications with EventMachine and EM::Synchrony
Fast, concurrent ruby web applications with EventMachine and EM::SynchronyKyle Drake
 
Codebits Handivi
Codebits HandiviCodebits Handivi
Codebits Handivicfpinto
 
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)Charles Nutter
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?Hiroshi SHIBATA
 
Node.js Patterns and Opinions
Node.js Patterns and OpinionsNode.js Patterns and Opinions
Node.js Patterns and OpinionsIsaacSchlueter
 
TRICK2015 results
TRICK2015 resultsTRICK2015 results
TRICK2015 resultsmametter
 
Culerity - Headless full stack testing for JavaScript
Culerity - Headless full stack testing for JavaScriptCulerity - Headless full stack testing for JavaScript
Culerity - Headless full stack testing for JavaScriptThilo Utke
 
Starting with Symfony2
Starting with Symfony2Starting with Symfony2
Starting with Symfony2Kevin Bond
 

Tendances (20)

Charles nutter star techconf 2011 - jvm languages
Charles nutter   star techconf 2011 - jvm languagesCharles nutter   star techconf 2011 - jvm languages
Charles nutter star techconf 2011 - jvm languages
 
Java tuning on GNU/Linux for busy dev
Java tuning on GNU/Linux for busy devJava tuning on GNU/Linux for busy dev
Java tuning on GNU/Linux for busy dev
 
Building MapAttack
Building MapAttackBuilding MapAttack
Building MapAttack
 
JRuby - The Best of Java and Ruby
JRuby - The Best of Java and RubyJRuby - The Best of Java and Ruby
JRuby - The Best of Java and Ruby
 
An introduction and future of Ruby coverage library
An introduction and future of Ruby coverage libraryAn introduction and future of Ruby coverage library
An introduction and future of Ruby coverage library
 
Expert JavaScript Programming
Expert JavaScript ProgrammingExpert JavaScript Programming
Expert JavaScript Programming
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013
 
Modern Java Concurrency (Devoxx Nov/2011)
Modern Java Concurrency (Devoxx Nov/2011)Modern Java Concurrency (Devoxx Nov/2011)
Modern Java Concurrency (Devoxx Nov/2011)
 
Rails development environment talk
Rails development environment talkRails development environment talk
Rails development environment talk
 
Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threads
 
IJTC%202009%20JRuby
IJTC%202009%20JRubyIJTC%202009%20JRuby
IJTC%202009%20JRuby
 
Fast, concurrent ruby web applications with EventMachine and EM::Synchrony
Fast, concurrent ruby web applications with EventMachine and EM::SynchronyFast, concurrent ruby web applications with EventMachine and EM::Synchrony
Fast, concurrent ruby web applications with EventMachine and EM::Synchrony
 
Codebits Handivi
Codebits HandiviCodebits Handivi
Codebits Handivi
 
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)
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?
 
Node.js Patterns and Opinions
Node.js Patterns and OpinionsNode.js Patterns and Opinions
Node.js Patterns and Opinions
 
TRICK2015 results
TRICK2015 resultsTRICK2015 results
TRICK2015 results
 
Culerity - Headless full stack testing for JavaScript
Culerity - Headless full stack testing for JavaScriptCulerity - Headless full stack testing for JavaScript
Culerity - Headless full stack testing for JavaScript
 
How to-node-core
How to-node-coreHow to-node-core
How to-node-core
 
Starting with Symfony2
Starting with Symfony2Starting with Symfony2
Starting with Symfony2
 

En vedette

Bitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBrian Sam-Bodden
 
JRuby on Rails
JRuby on RailsJRuby on Rails
JRuby on RailsFabio Kung
 
JRuby in the enterprise
JRuby in the enterpriseJRuby in the enterprise
JRuby in the enterpriseJerry Gulla
 
Import golang; struct microservice
Import golang; struct microserviceImport golang; struct microservice
Import golang; struct microserviceGiulio De Donato
 
Golang server design pattern
Golang server design patternGolang server design pattern
Golang server design pattern理 傅
 
Modern Web 2016: Using Golang to build a smart IM Bot
Modern Web 2016: Using Golang to build a smart IM Bot Modern Web 2016: Using Golang to build a smart IM Bot
Modern Web 2016: Using Golang to build a smart IM Bot Evan Lin
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golangBo-Yi Wu
 

En vedette (7)

Bitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRuby
 
JRuby on Rails
JRuby on RailsJRuby on Rails
JRuby on Rails
 
JRuby in the enterprise
JRuby in the enterpriseJRuby in the enterprise
JRuby in the enterprise
 
Import golang; struct microservice
Import golang; struct microserviceImport golang; struct microservice
Import golang; struct microservice
 
Golang server design pattern
Golang server design patternGolang server design pattern
Golang server design pattern
 
Modern Web 2016: Using Golang to build a smart IM Bot
Modern Web 2016: Using Golang to build a smart IM Bot Modern Web 2016: Using Golang to build a smart IM Bot
Modern Web 2016: Using Golang to build a smart IM Bot
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golang
 

Similaire à Subvert the JVM with JRuby Tricks

Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Charles Nutter
 
Ruby Midwest 2010 jRuby by Charles Nutter
Ruby Midwest 2010 jRuby by Charles NutterRuby Midwest 2010 jRuby by Charles Nutter
Ruby Midwest 2010 jRuby by Charles NutterSteven Chau
 
Messaging, interoperability and log aggregation - a new framework
Messaging, interoperability and log aggregation - a new frameworkMessaging, interoperability and log aggregation - a new framework
Messaging, interoperability and log aggregation - a new frameworkTomas Doran
 
The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018Charles Nutter
 
10 Things you should know about Ruby
10 Things you should know about Ruby10 Things you should know about Ruby
10 Things you should know about Rubysikachu
 
Scratching the itch, making Scratch for the Raspberry Pie
Scratching the itch, making Scratch for the Raspberry PieScratching the itch, making Scratch for the Raspberry Pie
Scratching the itch, making Scratch for the Raspberry PieESUG
 
Polyglot and Functional Programming (OSCON 2012)
Polyglot and Functional Programming (OSCON 2012)Polyglot and Functional Programming (OSCON 2012)
Polyglot and Functional Programming (OSCON 2012)Martijn Verburg
 
Introduction to JRuby
Introduction to JRubyIntroduction to JRuby
Introduction to JRubyajuckel
 
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)An Introduction to the Laravel Framework (AFUP Forum PHP 2014)
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)daylerees
 
Not Everything is an Object - Rocksolid Tour 2013
Not Everything is an Object  - Rocksolid Tour 2013Not Everything is an Object  - Rocksolid Tour 2013
Not Everything is an Object - Rocksolid Tour 2013Gary Short
 
Exploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLExploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLBarry Jones
 
MacRuby: What is it? and why should you care?
MacRuby: What is it? and why should you care?MacRuby: What is it? and why should you care?
MacRuby: What is it? and why should you care?Joshua Ballanco
 
Go: What's Different ?
Go: What's Different ?Go: What's Different ?
Go: What's Different ?Tarun Vashisth
 
Introduction to Go
Introduction to GoIntroduction to Go
Introduction to Gozhubert
 
Real time system_performance_mon
Real time system_performance_monReal time system_performance_mon
Real time system_performance_monTomas Doran
 

Similaire à Subvert the JVM with JRuby Tricks (20)

Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016
 
Ruby Midwest 2010 jRuby by Charles Nutter
Ruby Midwest 2010 jRuby by Charles NutterRuby Midwest 2010 jRuby by Charles Nutter
Ruby Midwest 2010 jRuby by Charles Nutter
 
Messaging, interoperability and log aggregation - a new framework
Messaging, interoperability and log aggregation - a new frameworkMessaging, interoperability and log aggregation - a new framework
Messaging, interoperability and log aggregation - a new framework
 
The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018
 
10 Things you should know about Ruby
10 Things you should know about Ruby10 Things you should know about Ruby
10 Things you should know about Ruby
 
Scratching the itch, making Scratch for the Raspberry Pie
Scratching the itch, making Scratch for the Raspberry PieScratching the itch, making Scratch for the Raspberry Pie
Scratching the itch, making Scratch for the Raspberry Pie
 
Euruko 2012 - JRuby
Euruko 2012 - JRubyEuruko 2012 - JRuby
Euruko 2012 - JRuby
 
Polyglot and Functional Programming (OSCON 2012)
Polyglot and Functional Programming (OSCON 2012)Polyglot and Functional Programming (OSCON 2012)
Polyglot and Functional Programming (OSCON 2012)
 
Introduction to JRuby
Introduction to JRubyIntroduction to JRuby
Introduction to JRuby
 
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)An Introduction to the Laravel Framework (AFUP Forum PHP 2014)
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)
 
Not Everything is an Object - Rocksolid Tour 2013
Not Everything is an Object  - Rocksolid Tour 2013Not Everything is an Object  - Rocksolid Tour 2013
Not Everything is an Object - Rocksolid Tour 2013
 
Exploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLExploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQL
 
MacRuby: What is it? and why should you care?
MacRuby: What is it? and why should you care?MacRuby: What is it? and why should you care?
MacRuby: What is it? and why should you care?
 
Zero mq logs
Zero mq logsZero mq logs
Zero mq logs
 
Ruby on the JVM
Ruby on the JVMRuby on the JVM
Ruby on the JVM
 
Optimizing Java Notes
Optimizing Java NotesOptimizing Java Notes
Optimizing Java Notes
 
TSSJS 2011 - JRuby
TSSJS 2011 - JRubyTSSJS 2011 - JRuby
TSSJS 2011 - JRuby
 
Go: What's Different ?
Go: What's Different ?Go: What's Different ?
Go: What's Different ?
 
Introduction to Go
Introduction to GoIntroduction to Go
Introduction to Go
 
Real time system_performance_mon
Real time system_performance_monReal time system_performance_mon
Real time system_performance_mon
 

Plus de Charles Nutter

Down the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandDown the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandCharles Nutter
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMCharles Nutter
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015Charles Nutter
 
JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015Charles Nutter
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaCharles Nutter
 
Open Source Software Needs You!
Open Source Software Needs You!Open Source Software Needs You!
Open Source Software Needs You!Charles Nutter
 
InvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesInvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesCharles Nutter
 
Doing Open Source the Right Way
Doing Open Source the Right WayDoing Open Source the Right Way
Doing Open Source the Right WayCharles Nutter
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Charles Nutter
 
Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Charles Nutter
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Charles Nutter
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013Charles Nutter
 
Invokedynamic in 45 Minutes
Invokedynamic in 45 MinutesInvokedynamic in 45 Minutes
Invokedynamic in 45 MinutesCharles Nutter
 
Invokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesInvokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesCharles Nutter
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Charles Nutter
 
Aloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyAloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyCharles Nutter
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesCharles 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 2012Charles Nutter
 
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 YetCharles Nutter
 

Plus de Charles Nutter (20)

Down the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandDown the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM Wonderland
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVM
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015
 
JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
 
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
 
Doing Open Source the Right Way
Doing Open Source the Right WayDoing Open Source the Right Way
Doing Open Source the Right Way
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013
 
Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013
 
Down the Rabbit Hole
Down the Rabbit HoleDown the Rabbit Hole
Down the Rabbit Hole
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 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
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
 
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
 
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
 

Dernier

Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 

Dernier (20)

Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 

Subvert the JVM with JRuby Tricks

  • 2. Subverting the JVM All the tricks, hacks, and kludges we’ve use to make JRuby the best off-JVM language impl around.
  • 3. Intro • Charles Oliver Nutter • Principal Software Engineer • Red Hat, JBoss Polyglot Group • @headius • headius@headius.com
  • 4. Welcome! • My favorite event of the year • I’ve only missed one! • I will quickly talk through JRuby challenges • Not a comprehensive list. Buy me a beer. • Rest of you can help solve them
  • 5. Ruby • Dynamic, object-oriented language • Created in 90s byYukihiro Matsumoto • “matz” • Matz’s Ruby Interpreter (MRI) • Inspired by Python, Perl, Lisp, Smalltalk • Memes:TMTOWTDI, MINASWAN, CoC,
  • 6. # Output "I love Ruby"! say = "I love Ruby"! puts say! ! # Output "I *LOVE* RUBY"! say['love'] = "*love*"! puts say.upcase! ! # Output "I *love* Ruby"! # five times! 5.times { puts say }!
  • 7. JRuby • Ruby for the JVM and JVM for the Ruby • Started in 2001, dozens of contribs • Usually the fastest Ruby • At least 20 paid full-time man years in it • Sun Microsystems, EngineYard, Red Hat
  • 8. Ruby is Hard to Implement!
  • 9. Making It Go (Fast) • Parser-generator hacks • Multiple interpreters • Multiple compilers • JVM-specific tricks
  • 10. Parsing Ruby • Yacc/Bison-based parse.y, almost 12kloc • Very complex, not context-free • No known 100% correct parser that is notYACC-based
  • 11.
  • 12.
  • 13.
  • 14. JRuby’s Parser • Jay parser generator • Maybe 5 projects in the world use it • Our version of parse.y = 4kloc • Two pieces, one is for offline parsing • Works ok, but…
  • 15. Parser Problems! • Array initialization > 65k bytecode • Giant switch won’t JIT • Outlining the case bodies: better • Case bodies as runnables in machine: best • org/jruby/parser/RubyParser$445.class • Slow at startup (most important time!)
  • 16. Interpreter • At least four interpreters we’ve tried • Original: visitor-based • Modified: big switch rather than visitor • Experimental: stackless instr-based • Current: direct execution of AST • Execution state on artificial stack
  • 17. The New Way • JRuby 9000 introduces a new IR • Traditional-style compiler IR • Register-based • CFG, semantic analysis, type and constant propagation, all that jazz • Interpreter has proven it out…JIT next
  • 18. Mixed-Mode • JRuby has both interpreter and JIT • Cost of generating JVM bytecode is high • Our interpreter runs faster than JVM’s • A jitted interpreter is (much) faster than unjitted bytecode
  • 19. Native Execution • Early JIT compiler just translated AST • Bare-minimum semantic analysis • Eliminate artificial frame use • One-off opto for frequent patterns • Too unwieldy to evolve much
  • 20. New IR JIT • Builds off IR runtime • Per-instruction bytecode gen is simple • JVM frame is like infinite register machine • Potential to massively improve perf • Early unboxing numbers…
  • 21. Numeric loop performance 0 1.25 2.5 3.75 5 times faster than MRI 2.1 JRuby 1.7 Rubinius
  • 22. Numeric loop performance 0 15 30 45 60 times faster than MRI 2.1 JRuby 1.7 Rubinius Truffle Topaz 9k+unbox
  • 23. mandelbrot(500) 0 10 20 30 40 times faster than MRI 2.1 JRuby 9k + indy JRuby 9k + unboxing JRuby 9k + Truffle
  • 24. Whither Truffle? • RubyTruffle merged into JRuby • Same licenses as rest of JRuby • Chris Seaton continues to work on it • Very impressive peak numbers • Startup, steady-state…needs work • Considering initial use for targeted opto
  • 25. JVM Tricks • Lack of class hierarchy analysis in JIT • Manually split methods to beat limits • Everything is an expression, so exception- handling has to maintain current stack • Tweaking JIT flags will just make you sad • Unsafe
  • 26. IRubyObject public RubyClass getMetaClass(); RubyBasicObject private RubyClass metaClass; public RubyClass getMetaClass() { return metaClass; } RubyString RubyArray RubyObject obj.getMetaClass()
  • 27. public static RubyClass metaclass(IRubyObject object) {
 return object instanceof RubyBasicObject ?
 ((RubyBasicObject)object).getMetaClass() :
 object.getMetaClass();
 }
  • 28. Compatibility • Strings and Encodings • IO • Fibers • Difficult choices
  • 29. Strings • All arbitrary-width byte data is String • Binary data and encoded text alike • Many supported encodings • j.l.String, char[] poor options • Size, data integrity, behavioral differences
  • 30. The First Big Decision • We realized we needed a byte[] String • Had been StringBuilder-based until then • That meant a lot of porting… • Regex engine (joni) • Encoding subsystem (jcodings) • Low-level IO + transcoding (in JRuby)
  • 31. JOni • Port of Oniguruma regex library • Pluggable grammars + arbitrary encodings • Bytecode engine (shallow call stack) • Interruptible • Re-forked as char[] engine for Nashorn • https://github.com/jruby/joni
  • 32. Data:‘a’-‘z’ in byte[] Match /.*tuv(..)yz$/ 0s 1.5s 3s 4.5s 6s j.u.regex JOni
  • 33. Data:‘a’-‘z’ from IO Match /.*tuv(..)yz$/ 0s 0.7s 1.4s 2.1s 2.8s j.u.regex JOni
  • 34. Jcodings • Character tables • Used heavily by JOni and JRuby • Transcoding tables and logic • Replaces Charset logic from JRuby 1.7 • https://github.com/jruby/jcodings
  • 36. JRuby 9000 • Finished porting, connecting transcoders • New port of IO operations • Transcoding works directly against IO buffers; hard to simulate other ways • Lots of fun native (C) calls to emulate…
  • 37. Fibers • Coroutines, goroutines, continuations • MRI uses stack-swapping • And limits Fiber stack size as a result • Useless as a concurrency model • Useful for multiplexing operations • Try read, no data, go to next fiber
  • 38. Fibers on JRuby • Yep, they’re just native threads • Transfer perf with j.u.c utils is pretty close • Resource load is very bad • Spin-up time is bad without thread pool • So early or occasional fibers cost a lot • Where are you, coro?!
  • 39. Hard Decisions • ObjectSpace walks heap, off by default • Trace functions add overhead, off by default • Full coroutines not possible • C extension API too difficult to emulate • Perhaps only item to really hurt us
  • 40. Native Integration • Process control • More selectable IO • FFI layer • C extension API • Misc
  • 41. Ruby’s Roots • Matz is/was a C programmer • Early Ruby did little more than stitch C calls together • Some of those roots remain • ttys, fcntl, process control, IO, ext API • We knew we needed a solution
  • 42. JNA, and then JNR • Started with jna-posix to map POSIX • stat, symlink, etc needed to do basics • JNR replaced JNA • Wayne Meissner started his empire…
  • 43. The Cancer • Many off-platform runtimes are not as good as Hotspot • Many of their users must turn to C for perf • So, since many people use C exts on MRI, maybe we need to implement it? • Or get a student to do it…
  • 44. MRI C Extensions • Very invasive API • Direct pointer access, object internals, conservative GC, threading constraints • Like bridging one JNI to another • Experimental in JRuby 1.6, gone in 1.7 • Will not revisit unless new API
  • 45. FFI • Ruby API/DSL for binding C libs • Additional tools for generating that code • If you need to go native, it’s the best way • In use in production JRuby apps • ØMQ client, bson lib, sodium crypto, …
  • 46. Ruby FFI example class Timeval < FFI::Struct!   layout :tv_sec => :ulong,! :tv_usec => :ulong! end! ! module LibC!   extend FFI::Library!   ffi_lib FFI::Library::LIBC!   attach_function :gettimeofday,! [ :pointer, :pointer ],! :int! end! ! t = Timeval.new! LibC.gettimeofday(t.pointer, nil)
  • 48. Native in JRuby • POSIX stuff missing from Java • Ruby FFI DSL for binding C libs • Stdio • selection, remove buffering, control tty • Process launching and control • !!!!!!
  • 49. Process Control • Java’s ProcessBuilder/Process are bad • No channel access (no select!) • Spins up at least one thread per process • Drains child output ahead of you • New process API based on posix_spawn
  • 50. in_c, in_p = IO.pipe out_p, out_c = IO.pipe ! pid = spawn('cat -n', :in => in_c, :out => out_c, :err => 'error.log') ! [in_c, out_c].each(&:close) ! in_p.puts("hello, world") in_p.close ! puts out_p.read # => " 1 hello, world" ! Process.waitpid(pid)
  • 51. Usability • Backtraces • Command-line and launchers • Startup time
  • 52. Backtraces • JVM backtraces make Rubyists’ eyes bleed • Initially, Ruby trace maintained manually • JIT emits mangled class to produce a Ruby trace element • AOT produces single class, mangled method name • Mixed-mode backtraces!
  • 53. at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1061) at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:910) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892) at groovy.lang.Closure.call(Closure.java:279) at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMet hods.java:1911) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java: 1184) at org.codehaus.groovy.runtime.dgm$88.invoke(Unknown Source) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite $PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:270) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:52) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java: 124) at BootStrap.populateBootstrapData(BootStrap.groovy:786) at BootStrap.this$2$populateBootstrapData(BootStrap.groovy) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1061) at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:910) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1009) at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:910) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892) at
  • 54. at org.jruby.javasupport.JavaMethod.invokeStaticDirect(JavaMethod.java:362) at org.jruby.java.invokers.StaticMethodInvoker.call(StaticMethodInvoker.java:50) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136) at org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60) at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105) at org.jruby.ast.RootNode.interpret(RootNode.java:129) at org.jruby.evaluator.ASTInterpreter.INTERPRET_EVAL(ASTInterpreter.java:95) at org.jruby.evaluator.ASTInterpreter.evalWithBinding(ASTInterpreter.java:184) at org.jruby.RubyKernel.evalCommon(RubyKernel.java:1158) at org.jruby.RubyKernel.eval19(RubyKernel.java:1121) at org.jruby.RubyKernel$INVOKER$s$0$3$eval19.call(RubyKernel$INVOKER$s$0$3$eval19.gen) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:210) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:206) at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:599) at org.jruby.runtime.invokedynamic.InvocationLinker.invocationFallback(InvocationLinker.java:155) at ruby.__dash_e__.method__1$RUBY$bar(-e:1) at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:599) at org.jruby.runtime.invokedynamic.InvocationLinker.invocationFallback(InvocationLinker.java:138) at ruby.__dash_e__.block_0$RUBY$foo(-e:1) at ruby$__dash_e__$block_0$RUBY$foo.call(ruby$__dash_e__$block_0$RUBY$foo) at org.jruby.runtime.CompiledBlock19.yieldSpecificInternal(CompiledBlock19.java:117) at org.jruby.runtime.CompiledBlock19.yieldSpecific(CompiledBlock19.java:92) at org.jruby.runtime.Block.yieldSpecific(Block.java:111) at org.jruby.RubyFixnum.times(RubyFixnum.java:275) at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:599) at org.jruby.runtime.invokedynamic.InvocationLinker.invocationFallback(InvocationLinker.java:230) at ruby.__dash_e__.method__0$RUBY$foo(-e:1) at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:599) at org.jruby.runtime.invokedynamic.InvocationLinker.invocationFallback(InvocationLinker.java:138) at ruby.__dash_e__.__file__(-e:1)
  • 55.
  • 56. • org.jruby.RubyFixnum.times • org.jruby.evaluator.ASTInterpreter.INTERPRET_EVAL • rubyjit.Object$ $foo_3AB1F5052668B3CD74A0B4CD4999CF6A65E9 2973271627940.__file__ • ruby.__dash_e__.method__0$RUBY$foo
  • 57. Command Line • Rubyists typically are at CLI • Command line and tty must behave • Epic bash and .bat scripts • 300-500 lines of heinous shell script • Unusable in shebang lines • Repurposed NetBeans native launcher
  • 58. system ~/projects/jruby $ time bin/jruby.bash -v jruby 9000.dev-SNAPSHOT (2.1.2) 2014-07-27 9cca1ec Java HotSpot(TM) 64-Bit Server VM 24.45-b08 on 1.7.0_45-b18 [darwin-x86_64] ! real 0m0.126s user 0m0.092s sys 0m0.031s ! system ~/projects/jruby $ time bin/jruby.bash -v jruby 9000.dev-SNAPSHOT (2.1.2) 2014-07-27 9cca1ec Java HotSpot(TM) 64-Bit Server VM 24.45-b08 on 1.7.0_45-b18 [darwin-x86_64] ! real 0m0.124s user 0m0.089s sys 0m0.033s ! system ~/projects/jruby $ time jruby -v jruby 9000.dev-SNAPSHOT (2.1.2) 2014-07-27 9cca1ec Java HotSpot(TM) 64-Bit Server VM 24.45-b08 on 1.7.0_45-b18 [darwin-x86_64] ! real 0m0.106s user 0m0.080s sys 0m0.022s ! system ~/projects/jruby $ time jruby -v jruby 9000.dev-SNAPSHOT (2.1.2) 2014-07-27 9cca1ec Java HotSpot(TM) 64-Bit Server VM 24.45-b08 on 1.7.0_45-b18 [darwin-x86_64] ! real 0m0.110s user 0m0.085s sys 0m0.023s
  • 59. Console Support • Rubyists also typically use REPLs • Readline support is a must • jline has been forked all over the place • Looking into JNA-based readline now
  • 60. CLI == Startup Time • BY FAR the #1 complaint • May be the only reason we haven’t won! • We’re trying everything we can
  • 61. JRuby Startup -e 1 gem --help rake -T Time in seconds (lower is better) 0 2.5 5 7.5 10 C Ruby JRuby
  • 62. Tweaking Flags • -client mode • -XX:+TieredCompilation -XX:TieredStopAtLevel=1 • -X-C to disable JRuby’s compiler • Heap sizes, code verification, etc etc
  • 63. Nailgun? • Keep a single JVM running in background • Toss commands over to it • It stays hot, so code starts faster • Hard to clean up all state (e.g. threads) • Can’t get access to user’s terminal • http://www.martiansoftware.com/nailgun/
  • 64. Drip Isolated JVM ApplicationCommand #1 Isolated JVM ApplicationCommand #1 Isolated JVM ApplicationCommand #1
  • 65. Drip • Start a new JVM after each command • Pre-boot JVM plus optional code • Analyze command line for differences • Age out unused instances • https://github.com/flatland/drip
  • 66. Drip Init • Give Drip some code to pre-boot • Load more libraries • Warm up some code • Pre-execution initialization • Run as much as possible in background • We also pre-load ./dripmain.rb if exists
  • 67. $ cat dripmain.rb # Preload some code Rails always needs require File.expand_path('../config/application', __FILE__)
  • 68. JRuby Startup rake -T Time in seconds (lower is better) 0 2.5 5 7.5 10 C Ruby JRuby JRuby (best) JRuby (drip) JRuby (drip init) JRuby (dripmain)
  • 70. Hard Parts • 64k bytecode limit • Falling over JIT limits • String char[] pain • Startup and warmup • Coroutines • FFI at JVM level • Too many flags • Tiered compiler slow • Interpreter opto • Bytecode is a blunt tool • Indy has taken too long • Charlie may burn out
  • 71. ThankYou! • Charles Oliver Nutter • @headius • headius@headius.com • http://blog.headius.com