erjang erlang on the jvm
play

Erjang: Erlang on the JVM Kresten Krab Thorup Trifork Thursday, - PowerPoint PPT Presentation

@drkrab Erjang: Erlang on the JVM Kresten Krab Thorup Trifork Thursday, May 12, 2011 Erjang: Goals Learn Erlang Discover Actor Programming Meet great people Thursday, May 12, 2011 What is Erjang? Erjang is an execution


  1. @drkrab Erjang: Erlang on the JVM Kresten Krab Thorup Trifork Thursday, May 12, 2011

  2. Erjang: Goals • Learn Erlang • Discover “Actor Programming” • Meet great people Thursday, May 12, 2011

  3. What is Erjang? • Erjang is an execution engine for BEAM byte code, written in Java. • JIT -Compiles BEAM to JVM byte code. • Runtime uses shared heap model. • BIFs and drivers are written in Java. Thursday, May 12, 2011

  4. Your Erlang Program OTP Framework BEAM BEAM Emulator BIFs Your favorite OS Thursday, May 12, 2011

  5. Your Erlang Program OTP Framework BEAM ERJANG BIFs JVM Java Virtual Machine Your favorite OS Thursday, May 12, 2011

  6. Let’s see it in action... Thursday, May 12, 2011

  7. Erlang ≠ Erjang Shared heap ¬ Native drivers ¬ NIF Thursday, May 12, 2011

  8. Why Java? • JVM is everywhere (from mobile to AS/400) • JVM has many libraries / integrations. • JVM has 500+ man-years of engineering • JVM is fast (for Java-ish programs). • ... and I know JVM pretty well, ... Thursday, May 12, 2011

  9. These are experimenting... StreamBase (CEP) Running Erlang-based FSMs on event streams ErlangIDE (Eclipse) Run compiler, type analysis, etc. Thursday, May 12, 2011

  10. Erjang - Challenges • Tail-recursion • Interfacing to Java • Ultra Light-Weight Processes • Real-time Behavior • Arbitrary Precision Numbers • Erlang Drivers • JVM is safe, urgh! Thursday, May 12, 2011

  11. JIT Compiler BEAM Reader ring.beam Type Analysis JVM Codegen ring-2a149ada.jar Thursday, May 12, 2011

  12. * JIT Compiler error_handler:undefined_function erlang:load_module BEAM Reader ring.beam Type Analysis ClassLoader.loadClass(“erjang.m.ring”) JVM Codegen ring-2a149ada.jar Thursday, May 12, 2011

  13. Erlang ⇒ JVM • Module ⇒ Class (+support in a “.jar”) • Function ⇒ Static Method + “EFun” object • Value ⇒ Object Instance ETuple, EPair, EFun, ESmall, EBig, ... Thursday, May 12, 2011

  14. Erlang ⇒ JVM -module(bar). process([H | T], T2) -> process(T, foo(H, T2)); process([], T2) -> T2. foo(H, T) -> lists:reverse(H ++ T). Thursday, May 12, 2011

  15. The BEAM Code {function, process, {nargs,2}}. {label,264}. {test,is_nonempty_list,{else,265},[{x,0}]}. {get_list,{x,0},{x,0},{y,0}}. {call,2,foo}. {move,{x,0},{x,1}}. {move,{y,0},{x,0}}. {call_last,2,process,1}. {label,265}. {test,is_nil,{else,263},[{x,0}]}. {move,{x,1},{x,0}}. return. {label,263}. {func_info,{atom,appmon_bar},{atom,process},2}. Thursday, May 12, 2011

  16. public static EObject process___2(EProc eproc, EObject arg1, EObject arg2) { ECons cons; ENil nil; tail: if((cons = arg1.test_nonempty_list()) != null) { // extract list EObject hd = cons.head(); EObject tl = cons.tail(); // call foo/2 EObject tmp = foo___2$call(eproc, hd, arg2); // self-tail recursion arg1 = tl; arg2 = tmp; goto tail; } else if ((nil = arg1.test_nil()) != null) { return arg2; } throw ERT.func_info(am_bar, am_process, 2); } Thursday, May 12, 2011

  17. DEMO • c(foo). • c(foo). • foo:main(). Thursday, May 12, 2011

  18. Erlang ⇒ JVM -module(bar). process([H | T], T2) -> process(T, foo(H, T2)); process([], T2) -> T2. foo(H, T) -> lists:reverse(H ++ T). Thursday, May 12, 2011

  19. foo(H, T) -> lists:reverse(H ++ T). public static EObject foo__2(EProc p, EObject H, EObject T) { EObject r = foo__2$body(p,H,T); while (r == TAIL_MARKER) { r = p.tail.go(); } return r; } Thursday, May 12, 2011

  20. foo(H, T) -> lists:reverse(H ++ T). public static EObject foo__2$body(EProc p, EObject H, EObject T) { // Tmp = erlang:’++’(H,T) EObject tmp = erlang_append__2.invoke(p,H,T); // return lists:reverse(Tmp) p.tail = lists__reverse_1; p.arg1 = tmp; return TAIL_MARKER; } Thursday, May 12, 2011

  21. foo(H, T) -> lists:reverse(H ++ T). package erjang.m.bar; class bar extends ECompiledModule { @Import(module=“lists”, fun=“reverse”, arity=1) static EFun1 lists__reverse__1 = null; @Import(module=“erlang”, fun=“++”, arity=2) static EFun2 erlang__append__2 = null; ... } Thursday, May 12, 2011

  22. Interface to Java • Calling to JAVA from ERJANG • BIFs: special calling convention • Plain Java: Type conversions • Calling ERJANG from JAVA Thursday, May 12, 2011

  23. Example BIF // foo:bar(...) native Function package erjang.m.foo; class foo extends ENative { @BIF public static EObject bar(EProc proc, EObject arg1, arg2, ...) { } } Thursday, May 12, 2011

  24. Example BIF @BIF public static EObject spawn_link(EProc proc, EObject mod, EObject fun, EObject args) throws Pausable { EAtom m = mod.testAtom(); EAtom f = fun.testAtom(); ESeq a = args.testSeq(); if (m==null||f==null||a==null) throw ERT.badarg(mod, fun, args); EProc p2 = new EProc(proc.group_leader(), m, f, a); p2.link_to(proc); ERT.run(p2); return p2.self_handle(); } Thursday, May 12, 2011

  25. demo() -> Map = 'java.util.HashMap':new(), Map:put('x', "4"), Map:put(1, 'foo'), print(Map). print([]) -> ok; print([{Key,Val}|Tail]) -> io:format("key=~p, value=~p~n", [Key,Val]), print(Tail). Thursday, May 12, 2011

  26. � � new Thread() { � � � { � � � � setDaemon (true); � � � � start (); � � � } � � � public void run() { � � � � String [] ARGS = { � � � � � � "-progname" , "ej" , � � � � � � "-home" , System . getProperty ( "user.home" ), � � � � � � "-root" , "/Users/krab/Projects/OTP_R13B04" , � � � � � � "+A" , "2" , � � � � � � "+S" , "1" , � � � � � � "+e" , "5.7.5" , � � � � � � "-s" , "rpc" , "erjang_started" � � � � � }; � � � � try { � � � � � erjang . Main . main ( ARGS ); � � � � } catch ( Exception e ) { � � � � � e . printStackTrace (); � � � � } � � � }; � � }; Thursday, May 12, 2011

  27. � � // � � // The -s rpc erjang_started argument // makes the loader call rpc:erjang_started/0 � � // which is the trigger that will release // 'wait_for_erjang_started' � � // � � System . err . println ( "did launch Erjang, ... waiting" ); � � RPC . wait_for_erjang_started ( 60 * 1000L ); � � � � // � � // Call erlang:display( ["Hello, Joe!~n", []] ) � � // � � EString hello_str = EString . fromString ( "Hello, Joe!~n" ); � � ESeq format_args = EList . make ( hello_str , ERT . NIL ); � � � � RPC . call ( am_erlang , am_display , ( EObject ) format_args ); Thursday, May 12, 2011

  28. Light-Weight Processes • Threads don’t cut it. • Erjang uses Kilim , a JVM byte code rewriter • Allows scheduling processes onto threads. Thursday, May 12, 2011

  29. Kilim ;":") ",,-&"&%. &'!%( /'&%( !"#$% $#) )*%)+ )-.% 345 *%"! 2$-1"&2-, /'&%( &#",$6-#0 %<&%#,"1 0-.%1 )*%)+ )-.% ",,-&"&2-,$ 7212089%":%# http://www.malhar.net/sriram/kilim/ Thursday, May 12, 2011

  30. Kilim Rewriting int execute() throws Pausable { msg = mbox.get(); return msg.size(); } Thursday, May 12, 2011

  31. Kilim Rewriting int execute() throws Pausable { throw KilimError(); } int execute(Fiber f) throws Pausable { msg = mbox.get(f); return msg.size(); } Thursday, May 12, 2011

  32. Kilim Rewriting int execute(Fiber f) throws Pausable { f.down(); msg = mbox.get(f); switch(f.up()) { case PAUSING|NO_STATE: f.setState(new State( locals )); case PAUSING|HAS_STATE: return 0; case RUNNING|HAS_STATE: locals = f.getState(); case RUNNING|NO_STATE: } return msg.size(); } Thursday, May 12, 2011

  33. Kilim Rewriting void execute(Fiber f) throws Pausable { switch (f.pc) { case 0: // default f.down(); mbox.get(f); switch(f.up()) { case PAUSING|NO_STATE: f.setState(new State( ... locals... )); case PAUSING|HAS_STATE: return 0; case NORMAL|HAS_STATE: locals = f.getState(); case NORMAL|NO_STATE: } case 1: // default return msg.size(); } } Thursday, May 12, 2011

  34. The ring! Thursday, May 12, 2011

  35. Thursday, May 12, 2011

  36. Thursday, May 12, 2011

  37. Test Setup erjang01.hosted.netic.dk • All run as JUnit tests (wrappers generated) • Comparison runs Module :test() Erjang vs BEAM • Running TRIQ tests comparison/local • Run Erlang test_server based tests (single- node mode) • Plain old JUnit tests Thursday, May 12, 2011

  38. erl - boot time Thursday, May 12, 2011

  39. erl - boot memory Thursday, May 12, 2011

  40. EStones Thursday, May 12, 2011

  41. @drkrab Java 8 • MethodHandle • Tail calls • Coroutines Would not be surprised to see Erjang 10x speedup Thursday, May 12, 2011

  42. @drkrab Erjang • It’s real • It’s fast • ... still lots to do. Thursday, May 12, 2011

  43. Thursday, May 12, 2011

Recommend


More recommend