
One VM to Rule Them All - pron
http://medianetwork.oracle.com/video/player/2623645003001/
======
derefr
So... can I run Erlang code on it efficiently? (This question also
disqualifies LLVM, the JVM, the CLR, etc. When most people say "universal VM"
they really mean "universal VM for running mostly-serial code that might at
most have 5 or 10 threads, and where killing and restarting the entire VM (to,
e.g., spin up a newer version) isn't a big problem for the clients talking to
it." This is not future-proof.)

~~~
pron
You can already run Erlang code efficiently on the JVM:
[https://github.com/trifork/erjang](https://github.com/trifork/erjang)

~~~
derefr
I can't tell from the precis whether it supports hot code loading (the JVM
doesn't, so it won't without heavy magic); and it definitely doesn't work in a
soft-realtime manner ("In Erjang, every node runs on a single heap, and so
global GC will sometimes happen.") Without these two things, you're not
"running Erlang code efficiently"; you're just running a pretty-useless-for-
its-intended-purpose subset of the language.

It's a bit like those benchmarks that show that a language that's a subset of
Ruby, performs much faster than actual Ruby. Well, yes, that's nice--but we
use Ruby precisely for all the inherently-really-slow parts. Once you add all
the slow stuff, and have to check whether to branch to it at every call, your
speed advantage stops being nearly so impressive.

Erlang is a painful language to code in; you don't do it because it's pretty.
You do it for what the BEAM VM and the OTP libraries give you: the ability to
spawn 100k processes representing, say, people's phone calls, or their MMO
game sessions, and not drop any connections for something piffling like a
garbage collection pass, or a bugfix. I would expect no less of any
"universal" VM. (Though I might, of course, expect _more_. It should probably
be able to do CPU-bound stuff like large matrix multiplications without
dragging the rest of the VM down, for example.)

~~~
chii
Not knowing much at all about erlang (other than its apparent software
uptime), could you briefly tell me how erlang achieves such amazing
performance and reliability? Is it due to the way erlang code is written
(which is pretty functional looking to me) more than the vm's inherent
structure, or a bit of both?

~~~
derefr
Erlang isn't really _performant_ in the way I think you're using the word. It
has okay speed, but you don't want to write your game's physics engine in it.
On the other hand, its _concurrent_ performance is great--you can load up a VM
with tons and tons of processes, and as long as none of them _individually_
are pegging the CPU, the VM will efficiently get them all evaluated.

Basically, the key to this is a combination of Erlang's use of tail-calls as
the only means of looping, and the VM's use of what I might call (I'm not
actually sure of the name for it) "hybrid budget-based cooperative/pre-emptive
scheduling."

Since all loops are implemented as tail-calls, every Erlang function
effectively is a straight O(N)-time-for-N-instructions shot that ends in
either another call (which either adds, or reuses a stack frame) or a return.
This gives the VM the opportunity to _act_ like a pre-emptive machine, while
gaining the _advantages_ of cooperative multitasking.

In cooperatively multitasked VMs, where coroutines have to explicitly "yield"
to pass the baton, you get a huge advantage: since the instruction-set
architecture can be designed to ensure that memory is in a well-defined state
whenever you yield, you don't have to do the expensive context-switch thing
that pre-emptive architectures do: stashing and unstashing registers,
switching out memory descriptors, etc. It can literally just be a jmp
instruction.

BEAM is basically a cooperatively-multitasked VM, except that every "call"
instruction is also an implicit "yield". (More specifically, it's a "yield if
this process has executed >= 2000 call instructions since it received
control.") So you get everything nice about cooperative multitasking (you
never decode only 0.8 of an audio frame before being interrupted), and
everything nice about pre-emptive multitasking (nothing can hog the processor
forever[1]), together; thus, soft real-time.

Another place where this design comes into play is in hot code loading. The
design of the loader itself is pretty simple: modules are kept in a hash-
table, keyed by name. A module is referenced by address on the stack, and in
loaded (threaded) bytecode; and by key in unloaded (abstract) bytecode. When
you upgrade a module, you just replace the value of the key in the module
dictionary. Functions that call other functions in their own module as they're
running stay in the previous version of a module; other functions that try to
jump into the module--or functions from the module that make a "remote"
(fully-qualified) call back into the module--jump into the new version.

This would be a lot harder and more complex, if we didn't have that guarantee
that every looping construct in Erlang is implemented in terms of tail-calls.
Since they are, we don't have to worry about "interrupting" a process to
upgrade it when it still has some dirty state; we can just wait around, and
every process will yield after a few microseconds, and we can upgrade it then,
when its state is well-defined.

\---

[1] --unless you call into C and that C code does something that takes a
million years. This is why people tell you to not do CPU-bound things in
Erlang. The semantics of BEAM's instruction-set architecture (and therefore
its non-optimal speed) is essential to how it multitasks; you have to insert
explicit process-yielding checks in your C code if you want it to be "non-
blocking." Or you can write your C code as a "port", which means letting the
OS manage it as a separate process--which, if you're writing one global
matrix-transformer process or one per-MMO-zone physics-engine process, isn't
that bad; but if you're writing a per-user speech-to-text analyzer, you've
handed your OS the job of managing 100k real native processes. Better to just
write it in plain Erlang, let the VM do its concurrency thing, take the speed
hit, and scale horizontally a bit sooner than you would have had to with C.
(Erlang is _great_ at scaling horizontally.)

~~~
pron
Curiously enough, _all_ of the features you've mentioned are doable on the
JVM, even without TCO support (I know this because I've worked on implementing
them in
[https://github.com/puniverse/quasar](https://github.com/puniverse/quasar) –
well, except for the "budget-based yield" but that's a minor change). The
general idea is that instead of providing the implementation baked into the
VM, you inject it into the compiled code using bytecode instrumentation (at
load or compile time).

What truly separates BEAM from the JVM is the almost total process isolation,
particularly, as you've mentioned, in the case of memory allocation and
reclamation. This difference, however, entails tradeoffs – sometimes you'd
want the one and sometimes the other.

~~~
derefr
Not so curious; this is the true meaning of Turing-completeness at work (not
the pop meaning programmers use in reference to programming languages.) You
can always write a virtual machine with semantics Y, that both executes on top
of another Turing-complete abstract machine with semantics X, and reads X
machine-code--and thus get semantics Y on machine X.

What you've effectively done is to just skip the naive VM-emulator step, and
move to the optimization of _dynamic recompilation_ , where you move the
state-transitions and additional semantics from the X interpreter, into the
chunks of X machine-code it would operate on. You've still implemented a Y VM;
it's just distributed throughout the code output by the compiler.

[For the same reason, I'm planning to port BEAM to asm.js. Why? Because _pre-
emptive concurrency_ is just an abstract-machine semantic, and you can get it
from a non-pre-emptively concurrent platform using the exact logic above. No
more callbacks! (If everything that uses asm.js has Web Worker support,
though, they could be used as run queues vis. BEAM's SMP support, leaving the
UI thread a lot less stressed.)]

~~~
pron
Well, Yes, but the result still benefits from the JVMs awesome performance
with regards to optimizations and memory management, and its terrific
monitoring and management tools. So, true, you lose some of BEAM's process
isolation, but you gain performance and tooling.

So I don't know if the JVM is universal in the sense that it can provide an
efficient implementation for all known or future languages, but it can
certainly serve as a very good Erlang VM.

Actually, Javascript is a bigger challenge than Erlang for the JVM. In Erlang
there's no dynamic dispatch, while in Javascript you have nothing but. So a
different kind of JIT might be better suited for Javascript.

------
saurik
[https://news.ycombinator.com/item?id=6232240](https://news.ycombinator.com/item?id=6232240)

------
chc
So now it isn't only Oracle's detractors equating it with the Dark Lord.

------
VeejayRampay
Does this mean that we can expect faster versions of the languages laid out in
the presentation (Python, Ruby, etc)?

~~~
pron
To judge by the results they present for Ruby, I assume the answer is yes.

~~~
VeejayRampay
This got me excited yeah, but the main issue is always that of the ETA. I do
love Ruby, wouldn't use any other language really, but damn would a little
speed boost be nice.

And of course I want it for free. Once all the goodness for JRuby, Rubinius
and that Oracle stuff get shaken for a long enough time, I guess we should see
the benefits in our everyday-coding.

------
m_ram
I read "Oracle" and "VM" in the title and immediately thought that VirtualBox
was going to be OpenOffice/MySQL-ized. I don't know how VirtualBox fits into
Oracle's strategy, but I'm glad that they're not messing with it.

~~~
nodata
I read Oracle in the title, and immediately closed the tab.

~~~
trailfox
Always good to see such well reasoned technical discussion here on HN. You
make a particularly well-reasoned point about the text in the title and how it
affects the technical aspects of the VM.

~~~
ihsw
Please don't be passive-aggressive, it's perfectly fine to call people out for
being narrow-minded and, dare I say, lazy.

However it's hard to deny that there's a very large stigma attached to the
name "Oracle."

------
SEJeff
Isn't think supposedly what parrot[1] is supposed to be for? Granted the perl
6 stuff under parrot is practically a laughing stock amongst much of the tech
community, but they are trying to make something awesome.

[1] [http://www.parrot.org/](http://www.parrot.org/)

~~~
chromatic
That was one of the goals of Parrot, but that P6 mess eventually chased off
almost all of Parrot's developers:

[http://www.modernperlbooks.com/mt/2013/02/goodnight-
parrot.h...](http://www.modernperlbooks.com/mt/2013/02/goodnight-parrot.html)

------
gary4gar
Interesting. Wondering, if the ruby implementation they wrote for demo
available? Want to play around with it. How do I install it?

------
jaydub
... and in the darkness (of Oracle) bind them!

------
toolslive
well, to stop people from panicking; in this context "All" means just a few.

It seems they have been building their own CLR.

~~~
trailfox
Why would people "panic" if Oracle builds them a better VM or the tools to
build a better Ruby/Python/Java VM?

It's quite different to the CLR. The CLR lets you implement any language you
like, as long as it can basically be mapped to C# constructs, not that
different from the JVM.

What Snoracle is working on is more generic with much higher performance.

~~~
darklajid
The CLR supports things that C# the language doesn't. C# isn't the common
denominator here, it's just one of the languages running on the CLR (and
probably? the most well-known). VB.Net and F# are equals, not to mention all
the non-MS languages that exist.

C# isn't special and doesn't represent the CLR's potential. It certainly might
drive the evolution of the CLR to a point.

------
brokenparser
In related news, Oracle still doesn't support HTML5. Back to you, pron.

~~~
spuz
Oracle is a database. What features of HTML5 have anything to do with
databases? How is this related to the article?

~~~
cowsandmilk
he's talking about their website... and oracle isn't just a database company
the last I checked. I mean, they make sparc servers. And VirtualBox. And Java.

~~~
spuz
If he was talking about the company, it would be an even stranger thing to
say. As we are not talking about a technology the only way it could be
interpreted is that Oracle (the company) does not 'tolerate' HTML5 as if they
have something against it. If he was talking about another of their
technologies he should have said so.

------
icefox
What about vmkit?

