SlideShare a Scribd company logo
Erjang—
a JVM-based Erlang VM

   Kresten Krab Thorup, Trifork
Erjang - A journey into Erlang-land
My Goal Today

• Erjang is an exploration project.
• Today I will show that it is viable.
• I cannot complete it myself.
• I need to find people who want to help
  make it complete, and build a
  community.
I’m an Explorer
                                                I’m an explorer




Illustration for french edition : Comment j'ai retrouvé Livingstone. Paris : Hachette, 1876.
Title : Rencontre de Livingstone
Why?
• Trends
 • Multi core / network-on-chip CPUs
 • Distributed / Cloud services composition
• Thus, we need to make it easy to...
 • Do distributed/concurrency
    programming
 • Make such systems reliable
What factors increase our
Capacity for Complexity?

A. Our system’s ability to perform and
   scale as problem size grows.
B. Our ability to understand and
   reason about systems
   as they grow big.
What factors increase our
Capacity for Complexity?

A. Our system’s ability to perform and
   scale as problem size grows.
B. Our ability to understand and
   reason about systems
   as they grow big.           I’m an
                               intuitive
                               person...
complexity ability




time
complexity ability




time
complexity ability   performance / scaleability




                                                  time
complexity ability   performance / scaleability




                                  dynamic
                              virtual machines



                                                  time
complexity ability   performance / scaleability

                                                   multi-core
                                                   hardware


                                  dynamic
                              virtual machines



                                                  time
complexity ability   performance / scaleability

                     understandability             multi-core
                                                   hardware


                                  dynamic
                              virtual machines



                                                  time
complexity ability   performance / scaleability

                     understandability             multi-core
                                                   hardware


                               object-oriented
                                  modeling



                                                  time
complexity ability   performance / scaleability

                     understandability             concurrency
                                                    modeling?


                               object-oriented
                                  modeling



                                                  time
Concurrency Landscape
     Explicit /    Implicit /
     Reactive     Functional
Concurrency Landscape
         Explicit /    Implicit /
         Reactive     Functional


 Here we need to
 understand and
  reason about
   parallelism
Concurrency Landscape
         Explicit /        Implicit /
         Reactive         Functional


 Here we need to        Here, we
 understand and       abstract the
  reason about         parallelism
   parallelism           away
Concurrency Landscape
                   Explicit /          Implicit /
                   Reactive           Functional

Distributed    Telephone Systems     Search Engine
                Trading Systems        Indexing

               Erlang / CORBA      Model Simulations,
              Message Middleware   Weather Forecasts

     Local     GUI-applications    Google/Hadoop
               Control Systems      Map-Reduce
                                   Data-Parallelism
                   Threads
Trend in “New”
Concurrency Languages

• Clojure          • Comprehending
                     concurrent systems is
• F#                 difficult
• Scala + Actors   • Mutable state is bad
• Erlang           • Make things simpler
Understanding                      Learning by
                                Doing: Don't Dissect
Actors                           the Frog, Build It.

 • To really understand actors,
    I wrote a simple actor framework for
    Java.
 • Each “actor” has an interface, and a
    behavior that implements that interface.
 • The framework creates a proxy that
    implement the interface and dispatches via
    a thread pool...
Java Actor Framework
client
          «interface»         «abstract class»

         Logger         ActorBehavior

                                      «class»

         Proxy          LoggerBehavior



         Thread Pool
Java Actor Framework
// the actor’s interface
interface Logger {
   void log(String val);
}

// ... and it’s behavior
class LoggerBehavior extends ActorBehavior<Logger> {
  void log(String val) { System.out.println(value); }
}

// ... then use it like this...
Logger logger = new LoggerBehavior().actor();
logger.log(“Something happened”);
Issues with this approach
Sharing. If an actor receives a reference to
a shared object then multiple actors/threads
may mutate that object concurrently.
Threads. If an actor blocks during it’s
operation, it is holding a precious resource,
namely a thread.
Concurrency. If the actor’s methods returns
a value, then the client will block, or what?
Why is Erlang interesting?

• Design context is suddenly relevant
• 20 years of experience in the community
• Real production use
 • Ericsson, CouchDB, Riak, ...
 • Amazon, Linked-in, ...
• Getting Popular ➟ Developer Availability
Erlang Principles

• Strategy for error handling
• Actors = Processes + Messaging
• Immutable Values
Reliable Systems
                   link
   Computer A             Computer B


• You need at least two pieces of hardware
  to make a reliable system; one monitors
  the other.
• Abstract this notion to software, and you
  have the Erlang error handling
  mechanism.
Reliable Systems
                  link
    Process A            Process B



• One process “supervises” the other
• Make code in “Process B” simpler
• Allow upgrade/modification of code in
  “Process A” when a new kind of failure
  appears.
Process ≡ Actor ≡ Object

• Erlang processes have many characteristics
  of objects
   • Identity
   • Polymorphism
   • Encapsulation
  “The way objects should have been”...
Erjang - Challenges
• Ultra Light-Weight Processes
• Real-time Behavior
• Tail-recursion
• Arbitrary Precision Numbers
• Pattern Matching
• Erlang Drivers
• JVM is type safe, urgh!
Erjang - Challenges
• Ultra Light-Weight Processes
• Real-time Behavior
• Tail-recursion
• Arbitrary Precision Numbers
• Pattern Matching
• Erlang Drivers
• JVM is type safe, urgh!
BEAM files

• Erlang modules compile to byte code
 • .BEAM file
 • Module ring in ring.beam
 • Similar to “Java .class file”
• .beam files are read by an “error handler”
  when missing modules/functions are seen.
Erjang Compiler


BEAM Reader        ring.beam


Type Analysis


JVM Codegen     ring-2a149ada.jar
Erjang BEAM Loading *
    erlang:load_module          error_handler:undefined_function




BEAM Reader                              ring.beam


Type Analysis            ClassLoader.loadClass(“erjang.m.ring”)




JVM Codegen                         ring-2a149ada.jar
Erjang BEAM Loading *
currently external
                     erlang:load_module          error_handler:undefined_function
  erlang service
 “beam_loader”



              BEAM Reader                                 ring.beam


              Type Analysis               ClassLoader.loadClass(“erjang.m.ring”)




              JVM Codegen                            ring-2a149ada.jar
Erjang BEAM Loading *
currently external
                       erlang:load_module          error_handler:undefined_function
  erlang service
 “beam_loader”



              BEAM Reader                                   ring.beam


              Type Analysis                 ClassLoader.loadClass(“erjang.m.ring”)




              JVM Codegen                              ring-2a149ada.jar

           package
         erjang.beam
Light-Weight Processes
• Threads don’t cut it;
 • Typical JVMs are limited to ~1000
    threads
 • Context switch for threads is very
    expensive
• Erjang uses Kilim, a separate project
• Run ~2-4 threads to utilize processors
Kilim
                                          Kilim: Isolation-Typed Actors for Java           105


                                 ;":")
       ",,-&"&%.                         &'!%(                 /'&%(
                         !"#$%
          $#)                            )*%)+                 )-.%




                                    *%"!           2$-1"&2-,              345      /'&%(
        %<&%#,"1                    0-.%1            )*%)+             &#",$6-#0   )-.%
       ",,-&"&2-,$
                                                 7212089%":%#

                Fig. 1. javac output post-processed by Kilim weaver


network and disk) [4] and service-oriented workflows. With a view to immedi-
ate industrial adoption, we impose the following additional requirements: (a) no
changes to Java syntax or to the JVM, (b) lightweight actors1 (c) fast messaging
(d ) no assumptions made about a message receiver’s location and implementa-
Kilim

• Rewrites code in methods declared
  ‘throws kilim.Pausable‘

    so that they can
• save call stack to “fiber data structure”
• and restore it later, continue execution...
Kilim Rewriting, in brief ...
                                     class Actor extends kilim.Task {
                                       void execute() { .. throw error ...}
                                       void execute(Fiber f) throws Pausable {
                                        switch (f.pc) {
                                        case 0:
class Actor extends kilim.Task {          f.down();
  void execute() throws Pausable {        mbox.get(f);
                                          switch(f.up()) {
     // also declared Pausable             case SAVE_STATE:
     mbox.get();                           case SAVE_NO_STATE:
 }                                           .. f.stack.push(new State(...));
}                                          case NORMAL_NO_STATE:
                                           case NORMAL_STATE:
                                          }
                                        }
                                      }
$"!!                                          &#!!!
             %&'()*                                          ()*+,-
             +,',-                                           ./*/0
                                                 &"!!!
   $!!!
                                                 &!!!!

   #"!!
                                                 %!!!

                                                 $!!!
   #!!!

                                                 #!!!
    "!!
                                                 "!!!

     !                                              !
     !        "!!!!   #!!!!!   #"!!!!   $!!!!!           !            &!!!   "!!!   '!!!


          (a) Creation and Destruction                           (b) Messaging

Fig. 11. Erlang vs. Kilim times. X-axis: n actors (n2 messages), Y-axis: Time in ms
(lower is better).


                                         Kilim
Kilim’s creation penalty is negligible (200,000 actors in 578ms, a rate of 350KHz),
and scaling is linear. We were unable to determine the reason for the knee in the
Erlang curve.
Messaging Performance. The second test (Fig. 11(b)) has n actors exchanging n2
messages with one another. This tests messaging performance and the ability to
make use of multiple processing elements (cores or processors). Kilim’s messaging
Pattern Matching

ins_opts([H | T], T2) ->
  ins_opts(T, ins_opt(H, T2));
ins_opts([], T2) -> T2.
The BEAM Code
 function, ins_opts, {nargs,2}}.
{label,264}.
  {test,is_nonempty_list,{else,265},[{x,0}]}.
  {get_list,{x,0},{x,0},{y,0}}.
  {call,2,ins_opt}.
  {move,{x,0},{x,1}}.
  {move,{y,0},{x,0}}.
  {call_last,2,ins_opts,1}.
{label,265}.
  {test,is_nil,{else,263},[{x,0}]}.
  {move,{x,1},{x,0}}.
  return.
{label,263}.
  {func_info,{atom,appmon_info},{atom,ins_opts},2}.
The BEAM Code
 function, ins_opts, {nargs,2}}.
{label,264}.
  {test,is_nonempty_list,{else,265},[{x,0}]}.
  {get_list,{x,0},{x,0},{y,0}}.
  {call,2,ins_opt}.
  {move,{x,0},{x,1}}.
  {move,{y,0},{x,0}}.
  {call_last,2,ins_opts,1}.
{label,265}.
  {test,is_nil,{else,263},[{x,0}]}.
  {move,{x,1},{x,0}}.
  return.
{label,263}.
  {func_info,{atom,appmon_info},{atom,ins_opts},2}.
public static EObject ins_opts___2(EProc eproc, EObject arg1,
    EObject arg2)
{
     tail: while(true) {
      ECons cons;
      if((cons = arg1.test_nonempty_list()) != null) {
          // extract list
          EObject hd = cons.head();
          EObject tl = cons.tail();
          // call ins_opt/2
          EObject tmp = ins_opt___2(eproc, hd, arg2);
          // self-tail recursion
          arg1 = tl;
          arg2 = tmp;
          continue tail;
      } else if ((arg1.test_nil()) != null) {
          return arg2;
      }
      throw ERT.func_info(atom_appmon_info, atom_ins_opts, 2);
    }
}
public static EObject ins_opts___2(EProc eproc, EObject arg1,
    EObject arg2)
{
     tail: while(true) {
      ECons cons;
      if((cons = arg1.test_nonempty_list()) != null) {
          // extract list
          EObject hd = cons.head();
          EObject tl = cons.tail();
          // call ins_opt/2
          EObject tmp = ins_opt___2(eproc, hd, arg2);
          // self-tail recursion
          arg1 = tl;
          arg2 = tmp;
          continue tail;
      } else if ((arg1.test_nil()) != null) {
          return arg2;
      }
      throw ERT.func_info(atom_appmon_info, atom_ins_opts, 2);
    }
}
Core Erjang Types
                                                EObject




                    ETuple          EAtom        EFun               ECons                ENumber




ETuple1   Etuple3      ETuple0   EFun0       EFun1        EFun2     ESeq       EPair     EInteger     EFloat




                                            Generated
                                                             ENil      EList           ESmall       EBig
                                             Function
ETuple
Subclasses ETupleN (for an n-tuple) are
generated on-demand, and distinct.
 elemN fields are public, but can only be
 accessed from generated code...
ETuple0, ETuple1 and ETuple2 hand coded;
otherwise use ETuple.make(EObject...)
Tuples in erlang are 1-indexed; coding
convention is to use idx1 for 1-indexed, and
idx0 for 0-indexed index variables.
ECons




 ECons & ESeq                         ESeq            EPair     EBinList




                               ENil   EList           EString




• ESeq is a well-formed list - similar to
  Clojure ISeq; .tail() is also an ESeq.
• EString is list of small integers [0..255]
• EPair is a non-well-formed list
• EBinList is [byte,byte,byte | Tail]
EFun / Functions
    	 abstract class EFun extends EObject {

	       /** generic invoke, used only for apply */
	       public abstract EObject apply(EProc proc, ESeq args)
             throws Pausable;

        /** used for of tail recursive calls */
	        public abstract EObject go(EProc eproc)
              throws Pausable;

    }
EFun / Functions
/** generated base class for functions with 2 arguments... */
abstract class EFun2 extends EFun {

	       /** generic invoke, used only for apply */
	     public abstract EObject apply(EProc proc, ESeq args) throws Pausable {
          EObject arg1 = args.head();
          EObject arg2 = args.tail().head();
          /* add error checking ... */
          return invoke(proc, arg1, arg2);
      }

      public EObject invoke(EProc proc, EObject arg1, EObject arg2)
           throws Pausable {
          EObject res = this.body(proc,arg1,arg2);
          while(res == TAIL_MARKER) { res = proc.tail.go(); }
          return res;
      }

...
EFun / Functions
/** generated base class for functions with 2 arguments... */
abstract class EFun2 extends EFun {

    ...

    public abstract EObject body(EProc proc, EObject arg1, EObject arg2)
        throws Pausable;

    public abstract EObject go(EProc proc)
        throws Pausable {
       EObject arg1 = proc.arg1;
       EObject arg2 = proc.arg2;
       proc.arg1 = null;
       proc.arg2 = null;
       proc.tail = null;
       return this.body(proc, arg1, arg2);
    }

}
Tail Recursion


  fibo_tr( 0, Result, _Next)
     -> Result; %% last recursion output
fibo_tr( Iter, Result, Next) when Iter>0
   -> fibo_tr( Iter -1, Next, Result + Next).

fibo(N) -> fibo_tr( N, 0, 1) .
Tail Recursion
class Fibo extends EFun3 {

  EObject body(EProc proc, EObject iter, EObject result, EObject next)
  {
     if (iter == Fibo.cst_zero) { return result; }
     if (ErlBif.op_gt_guard(iter, Fibo.cst_zero) != null) {
       proc.arg1 = iter.minus(Fibo.cts_one);
       proc.arg2 = next;
       proc.arg3 = result.plus(next);
       proc.tail = this;
       return TAIL_MARKER;
     }
     throw ERT.badmatch(iter,result,next);
  }

  EObject go(EProc proc) {
     return body(proc, proc.arg1, proc.arg2, proc.arg3);
  }
Demo!

Tail-recursive Fibonacci,
 10, 100, 1000, 10000, 100000


Ring example
 10.000 processes x 10.000 cycles
Interfacing to Java

• Erlang’s primitive operations “BIFs” are
  implemented in java - obviously
• @BIF annotation makes a static-public
  method available from Erlang.
• Erlang port concept for “drivers”
• Future of integration?
Status today?

• I’m working on OTP
  boot; i.e., getting to
  the prompt of “erl”
  command line.
• 83% there, measured
  by modules loaded/
  compiled.
Erjang - A journey into Erlang-land

More Related Content

PDF
JDK7: Improved support for dynamic languages
PDF
Challenges in Maintaining a High Performance Search Engine Written in Java
PDF
Ruby for C#-ers (ScanDevConf 2010)
PDF
At Scale With Style
PPTX
Advanced Silverlight
PPTX
basic core java up to operator
PDF
The Diabolical Developers Guide to Performance Tuning
PPT
Java withrealworldtechnology
JDK7: Improved support for dynamic languages
Challenges in Maintaining a High Performance Search Engine Written in Java
Ruby for C#-ers (ScanDevConf 2010)
At Scale With Style
Advanced Silverlight
basic core java up to operator
The Diabolical Developers Guide to Performance Tuning
Java withrealworldtechnology

Similar to Erjang - A journey into Erlang-land (20)

PDF
VoltDB and Erlang - Tech planet 2012
PPTX
Indic threads pune12-typesafe stack software development on the jvm
PPTX
Supporting Concurrency Abstractions in High-level Language Virtual Machines
PDF
Why Erlang? - Bar Camp Atlanta 2008
PDF
Scala in Model-Driven development for Apparel Cloud Platform
PPTX
Thinking in parallel ab tuladev
PPT
IS-ENES COMP Superscalar tutorial
PPTX
Systems Design Experiences or Just Some War Stories…
PDF
High level programming of embedded hard real-time devices
PPTX
Concurrency Constructs Overview
PDF
Martin Odersky: What's next for Scala
PDF
Erlang for video delivery
PDF
12 years supporting Software Architecture teaching with BEAMs
ODP
DevOps Days Vancouver 2014 Slides
PDF
Exploiting Concurrency with Dynamic Languages
ODP
An introduction to erlang
PDF
A Survey of Concurrency Constructs
PDF
Scala google
PPT
Current Trends in HPC
PDF
Sly and the RoarVM: Exploring the Manycore Future of Programming
VoltDB and Erlang - Tech planet 2012
Indic threads pune12-typesafe stack software development on the jvm
Supporting Concurrency Abstractions in High-level Language Virtual Machines
Why Erlang? - Bar Camp Atlanta 2008
Scala in Model-Driven development for Apparel Cloud Platform
Thinking in parallel ab tuladev
IS-ENES COMP Superscalar tutorial
Systems Design Experiences or Just Some War Stories…
High level programming of embedded hard real-time devices
Concurrency Constructs Overview
Martin Odersky: What's next for Scala
Erlang for video delivery
12 years supporting Software Architecture teaching with BEAMs
DevOps Days Vancouver 2014 Slides
Exploiting Concurrency with Dynamic Languages
An introduction to erlang
A Survey of Concurrency Constructs
Scala google
Current Trends in HPC
Sly and the RoarVM: Exploring the Manycore Future of Programming
Ad

Recently uploaded (20)

PDF
NewMind AI Weekly Chronicles - August'25-Week II
PPTX
Chapter 5: Probability Theory and Statistics
PDF
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
PDF
Heart disease approach using modified random forest and particle swarm optimi...
PDF
Enhancing emotion recognition model for a student engagement use case through...
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PPTX
A Presentation on Touch Screen Technology
PPTX
1. Introduction to Computer Programming.pptx
PPTX
A Presentation on Artificial Intelligence
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PDF
Web App vs Mobile App What Should You Build First.pdf
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
PDF
1 - Historical Antecedents, Social Consideration.pdf
PDF
Hybrid model detection and classification of lung cancer
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PDF
WOOl fibre morphology and structure.pdf for textiles
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
A novel scalable deep ensemble learning framework for big data classification...
NewMind AI Weekly Chronicles - August'25-Week II
Chapter 5: Probability Theory and Statistics
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
Heart disease approach using modified random forest and particle swarm optimi...
Enhancing emotion recognition model for a student engagement use case through...
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
A Presentation on Touch Screen Technology
1. Introduction to Computer Programming.pptx
A Presentation on Artificial Intelligence
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
Web App vs Mobile App What Should You Build First.pdf
A comparative analysis of optical character recognition models for extracting...
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
1 - Historical Antecedents, Social Consideration.pdf
Hybrid model detection and classification of lung cancer
Univ-Connecticut-ChatGPT-Presentaion.pdf
WOOl fibre morphology and structure.pdf for textiles
Programs and apps: productivity, graphics, security and other tools
A novel scalable deep ensemble learning framework for big data classification...
Ad

Erjang - A journey into Erlang-land

  • 1. Erjang— a JVM-based Erlang VM Kresten Krab Thorup, Trifork
  • 3. My Goal Today • Erjang is an exploration project. • Today I will show that it is viable. • I cannot complete it myself. • I need to find people who want to help make it complete, and build a community.
  • 4. I’m an Explorer I’m an explorer Illustration for french edition : Comment j'ai retrouvé Livingstone. Paris : Hachette, 1876. Title : Rencontre de Livingstone
  • 5. Why? • Trends • Multi core / network-on-chip CPUs • Distributed / Cloud services composition • Thus, we need to make it easy to... • Do distributed/concurrency programming • Make such systems reliable
  • 6. What factors increase our Capacity for Complexity? A. Our system’s ability to perform and scale as problem size grows. B. Our ability to understand and reason about systems as they grow big.
  • 7. What factors increase our Capacity for Complexity? A. Our system’s ability to perform and scale as problem size grows. B. Our ability to understand and reason about systems as they grow big. I’m an intuitive person...
  • 10. complexity ability performance / scaleability time
  • 11. complexity ability performance / scaleability dynamic virtual machines time
  • 12. complexity ability performance / scaleability multi-core hardware dynamic virtual machines time
  • 13. complexity ability performance / scaleability understandability multi-core hardware dynamic virtual machines time
  • 14. complexity ability performance / scaleability understandability multi-core hardware object-oriented modeling time
  • 15. complexity ability performance / scaleability understandability concurrency modeling? object-oriented modeling time
  • 16. Concurrency Landscape Explicit / Implicit / Reactive Functional
  • 17. Concurrency Landscape Explicit / Implicit / Reactive Functional Here we need to understand and reason about parallelism
  • 18. Concurrency Landscape Explicit / Implicit / Reactive Functional Here we need to Here, we understand and abstract the reason about parallelism parallelism away
  • 19. Concurrency Landscape Explicit / Implicit / Reactive Functional Distributed Telephone Systems Search Engine Trading Systems Indexing Erlang / CORBA Model Simulations, Message Middleware Weather Forecasts Local GUI-applications Google/Hadoop Control Systems Map-Reduce Data-Parallelism Threads
  • 20. Trend in “New” Concurrency Languages • Clojure • Comprehending concurrent systems is • F# difficult • Scala + Actors • Mutable state is bad • Erlang • Make things simpler
  • 21. Understanding Learning by Doing: Don't Dissect Actors the Frog, Build It. • To really understand actors, I wrote a simple actor framework for Java. • Each “actor” has an interface, and a behavior that implements that interface. • The framework creates a proxy that implement the interface and dispatches via a thread pool...
  • 22. Java Actor Framework client «interface» «abstract class» Logger ActorBehavior «class» Proxy LoggerBehavior Thread Pool
  • 23. Java Actor Framework // the actor’s interface interface Logger { void log(String val); } // ... and it’s behavior class LoggerBehavior extends ActorBehavior<Logger> { void log(String val) { System.out.println(value); } } // ... then use it like this... Logger logger = new LoggerBehavior().actor(); logger.log(“Something happened”);
  • 24. Issues with this approach Sharing. If an actor receives a reference to a shared object then multiple actors/threads may mutate that object concurrently. Threads. If an actor blocks during it’s operation, it is holding a precious resource, namely a thread. Concurrency. If the actor’s methods returns a value, then the client will block, or what?
  • 25. Why is Erlang interesting? • Design context is suddenly relevant • 20 years of experience in the community • Real production use • Ericsson, CouchDB, Riak, ... • Amazon, Linked-in, ... • Getting Popular ➟ Developer Availability
  • 26. Erlang Principles • Strategy for error handling • Actors = Processes + Messaging • Immutable Values
  • 27. Reliable Systems link Computer A Computer B • You need at least two pieces of hardware to make a reliable system; one monitors the other. • Abstract this notion to software, and you have the Erlang error handling mechanism.
  • 28. Reliable Systems link Process A Process B • One process “supervises” the other • Make code in “Process B” simpler • Allow upgrade/modification of code in “Process A” when a new kind of failure appears.
  • 29. Process ≡ Actor ≡ Object • Erlang processes have many characteristics of objects • Identity • Polymorphism • Encapsulation “The way objects should have been”...
  • 30. Erjang - Challenges • Ultra Light-Weight Processes • Real-time Behavior • Tail-recursion • Arbitrary Precision Numbers • Pattern Matching • Erlang Drivers • JVM is type safe, urgh!
  • 31. Erjang - Challenges • Ultra Light-Weight Processes • Real-time Behavior • Tail-recursion • Arbitrary Precision Numbers • Pattern Matching • Erlang Drivers • JVM is type safe, urgh!
  • 32. BEAM files • Erlang modules compile to byte code • .BEAM file • Module ring in ring.beam • Similar to “Java .class file” • .beam files are read by an “error handler” when missing modules/functions are seen.
  • 33. Erjang Compiler BEAM Reader ring.beam Type Analysis JVM Codegen ring-2a149ada.jar
  • 34. Erjang BEAM Loading * erlang:load_module error_handler:undefined_function BEAM Reader ring.beam Type Analysis ClassLoader.loadClass(“erjang.m.ring”) JVM Codegen ring-2a149ada.jar
  • 35. Erjang BEAM Loading * currently external erlang:load_module error_handler:undefined_function erlang service “beam_loader” BEAM Reader ring.beam Type Analysis ClassLoader.loadClass(“erjang.m.ring”) JVM Codegen ring-2a149ada.jar
  • 36. Erjang BEAM Loading * currently external erlang:load_module error_handler:undefined_function erlang service “beam_loader” BEAM Reader ring.beam Type Analysis ClassLoader.loadClass(“erjang.m.ring”) JVM Codegen ring-2a149ada.jar package erjang.beam
  • 37. Light-Weight Processes • Threads don’t cut it; • Typical JVMs are limited to ~1000 threads • Context switch for threads is very expensive • Erjang uses Kilim, a separate project • Run ~2-4 threads to utilize processors
  • 38. Kilim Kilim: Isolation-Typed Actors for Java 105 ;":") ",,-&"&%. &'!%( /'&%( !"#$% $#) )*%)+ )-.% *%"! 2$-1"&2-, 345 /'&%( %<&%#,"1 0-.%1 )*%)+ &#",$6-#0 )-.% ",,-&"&2-,$ 7212089%":%# Fig. 1. javac output post-processed by Kilim weaver network and disk) [4] and service-oriented workflows. With a view to immedi- ate industrial adoption, we impose the following additional requirements: (a) no changes to Java syntax or to the JVM, (b) lightweight actors1 (c) fast messaging (d ) no assumptions made about a message receiver’s location and implementa-
  • 39. Kilim • Rewrites code in methods declared ‘throws kilim.Pausable‘ so that they can • save call stack to “fiber data structure” • and restore it later, continue execution...
  • 40. Kilim Rewriting, in brief ... class Actor extends kilim.Task { void execute() { .. throw error ...} void execute(Fiber f) throws Pausable { switch (f.pc) { case 0: class Actor extends kilim.Task { f.down(); void execute() throws Pausable { mbox.get(f); switch(f.up()) { // also declared Pausable case SAVE_STATE: mbox.get(); case SAVE_NO_STATE: } .. f.stack.push(new State(...)); } case NORMAL_NO_STATE: case NORMAL_STATE: } } }
  • 41. $"!! &#!!! %&'()* ()*+,- +,',- ./*/0 &"!!! $!!! &!!!! #"!! %!!! $!!! #!!! #!!! "!! "!!! ! ! ! "!!!! #!!!!! #"!!!! $!!!!! ! &!!! "!!! '!!! (a) Creation and Destruction (b) Messaging Fig. 11. Erlang vs. Kilim times. X-axis: n actors (n2 messages), Y-axis: Time in ms (lower is better). Kilim Kilim’s creation penalty is negligible (200,000 actors in 578ms, a rate of 350KHz), and scaling is linear. We were unable to determine the reason for the knee in the Erlang curve. Messaging Performance. The second test (Fig. 11(b)) has n actors exchanging n2 messages with one another. This tests messaging performance and the ability to make use of multiple processing elements (cores or processors). Kilim’s messaging
  • 42. Pattern Matching ins_opts([H | T], T2) -> ins_opts(T, ins_opt(H, T2)); ins_opts([], T2) -> T2.
  • 43. The BEAM Code function, ins_opts, {nargs,2}}. {label,264}. {test,is_nonempty_list,{else,265},[{x,0}]}. {get_list,{x,0},{x,0},{y,0}}. {call,2,ins_opt}. {move,{x,0},{x,1}}. {move,{y,0},{x,0}}. {call_last,2,ins_opts,1}. {label,265}. {test,is_nil,{else,263},[{x,0}]}. {move,{x,1},{x,0}}. return. {label,263}. {func_info,{atom,appmon_info},{atom,ins_opts},2}.
  • 44. The BEAM Code function, ins_opts, {nargs,2}}. {label,264}. {test,is_nonempty_list,{else,265},[{x,0}]}. {get_list,{x,0},{x,0},{y,0}}. {call,2,ins_opt}. {move,{x,0},{x,1}}. {move,{y,0},{x,0}}. {call_last,2,ins_opts,1}. {label,265}. {test,is_nil,{else,263},[{x,0}]}. {move,{x,1},{x,0}}. return. {label,263}. {func_info,{atom,appmon_info},{atom,ins_opts},2}.
  • 45. public static EObject ins_opts___2(EProc eproc, EObject arg1, EObject arg2) { tail: while(true) { ECons cons; if((cons = arg1.test_nonempty_list()) != null) { // extract list EObject hd = cons.head(); EObject tl = cons.tail(); // call ins_opt/2 EObject tmp = ins_opt___2(eproc, hd, arg2); // self-tail recursion arg1 = tl; arg2 = tmp; continue tail; } else if ((arg1.test_nil()) != null) { return arg2; } throw ERT.func_info(atom_appmon_info, atom_ins_opts, 2); } }
  • 46. public static EObject ins_opts___2(EProc eproc, EObject arg1, EObject arg2) { tail: while(true) { ECons cons; if((cons = arg1.test_nonempty_list()) != null) { // extract list EObject hd = cons.head(); EObject tl = cons.tail(); // call ins_opt/2 EObject tmp = ins_opt___2(eproc, hd, arg2); // self-tail recursion arg1 = tl; arg2 = tmp; continue tail; } else if ((arg1.test_nil()) != null) { return arg2; } throw ERT.func_info(atom_appmon_info, atom_ins_opts, 2); } }
  • 47. Core Erjang Types EObject ETuple EAtom EFun ECons ENumber ETuple1 Etuple3 ETuple0 EFun0 EFun1 EFun2 ESeq EPair EInteger EFloat Generated ENil EList ESmall EBig Function
  • 48. ETuple Subclasses ETupleN (for an n-tuple) are generated on-demand, and distinct. elemN fields are public, but can only be accessed from generated code... ETuple0, ETuple1 and ETuple2 hand coded; otherwise use ETuple.make(EObject...) Tuples in erlang are 1-indexed; coding convention is to use idx1 for 1-indexed, and idx0 for 0-indexed index variables.
  • 49. ECons ECons & ESeq ESeq EPair EBinList ENil EList EString • ESeq is a well-formed list - similar to Clojure ISeq; .tail() is also an ESeq. • EString is list of small integers [0..255] • EPair is a non-well-formed list • EBinList is [byte,byte,byte | Tail]
  • 50. EFun / Functions abstract class EFun extends EObject { /** generic invoke, used only for apply */ public abstract EObject apply(EProc proc, ESeq args) throws Pausable; /** used for of tail recursive calls */ public abstract EObject go(EProc eproc) throws Pausable; }
  • 51. EFun / Functions /** generated base class for functions with 2 arguments... */ abstract class EFun2 extends EFun { /** generic invoke, used only for apply */ public abstract EObject apply(EProc proc, ESeq args) throws Pausable { EObject arg1 = args.head(); EObject arg2 = args.tail().head(); /* add error checking ... */ return invoke(proc, arg1, arg2); } public EObject invoke(EProc proc, EObject arg1, EObject arg2) throws Pausable { EObject res = this.body(proc,arg1,arg2); while(res == TAIL_MARKER) { res = proc.tail.go(); } return res; } ...
  • 52. EFun / Functions /** generated base class for functions with 2 arguments... */ abstract class EFun2 extends EFun { ... public abstract EObject body(EProc proc, EObject arg1, EObject arg2) throws Pausable; public abstract EObject go(EProc proc) throws Pausable { EObject arg1 = proc.arg1; EObject arg2 = proc.arg2; proc.arg1 = null; proc.arg2 = null; proc.tail = null; return this.body(proc, arg1, arg2); } }
  • 53. Tail Recursion fibo_tr( 0, Result, _Next) -> Result; %% last recursion output fibo_tr( Iter, Result, Next) when Iter>0 -> fibo_tr( Iter -1, Next, Result + Next). fibo(N) -> fibo_tr( N, 0, 1) .
  • 54. Tail Recursion class Fibo extends EFun3 { EObject body(EProc proc, EObject iter, EObject result, EObject next) { if (iter == Fibo.cst_zero) { return result; } if (ErlBif.op_gt_guard(iter, Fibo.cst_zero) != null) { proc.arg1 = iter.minus(Fibo.cts_one); proc.arg2 = next; proc.arg3 = result.plus(next); proc.tail = this; return TAIL_MARKER; } throw ERT.badmatch(iter,result,next); } EObject go(EProc proc) { return body(proc, proc.arg1, proc.arg2, proc.arg3); }
  • 55. Demo! Tail-recursive Fibonacci, 10, 100, 1000, 10000, 100000 Ring example 10.000 processes x 10.000 cycles
  • 56. Interfacing to Java • Erlang’s primitive operations “BIFs” are implemented in java - obviously • @BIF annotation makes a static-public method available from Erlang. • Erlang port concept for “drivers” • Future of integration?
  • 57. Status today? • I’m working on OTP boot; i.e., getting to the prompt of “erl” command line. • 83% there, measured by modules loaded/ compiled.