
What asm.js is and isn't - shardling
http://mozakai.blogspot.com/2013/06/what-asmjs-is-and-what-asmjs-isnt.html
======
derefr
To put it another way: asm.js is not separate virtual machine; it really is
"just Javascript", both in intention and when executed.

But it _is_ a separate _abstract machine_ with its own _formal semantics_ ,
including its own type system et al.

Don't get confused: you can treat _anything_ as an abstract machine and
formalize its semantics. For example, "x86 minus the PUSH and POP
instructions" could be formalized as an abstract machine that you can work
with. The resulting machine _only_ exists on the level of formalism; you might
actually execute the code you're written for this machine on an x86, just
having not emitted any LOADs or STOREs. In the same way, targeting the asm.js
abstract machine doesn't mean there has to be an asm.js VM: the formalism just
targets a subset of Javascript that current Javascript VMs already have useful
optimizations for.

------
wmf
I thought OdinMonkey was a new JIT (because it's a new monkey), so this
provided some useful if long-winded clarification.

~~~
ahomescu1
I thought so too originally, but it's not. It just emits IonMonkey SSA IR
directly from parsing asm.js (as far as I could tell fromr reading the code,
someone correct me if I'm wrong).

------
mixedbit
Great read. One thing worries me: if we standardize a subset of JavaScript
that browsers can execute quicker, won't it cause a decline in the use of
fully-featured, human-written JavaScript? Developers may reasonably choose to
write all their web code in languages that are compiled to asm.js subset. As a
result, we will lose benefits that a scripting language that is human edited
and readable gives.

~~~
octo_t
Surely this could have been a criticism of C?

Won't we lose the benefits of an assembly language that is human edited and
readable?

~~~
mixedbit
No, because assembler was not shipped to clients, it was compiled anyway to
unreadable binary. JavaScript is shipped to clients, you can open and examine
it (if it is not obfuscated).

~~~
ndesaulniers
`ndisasm your_binary | less` done!

------
mpyne
Worth reading the whole way through.

~~~
egeozcan
Exactly, and I was just starting to think that I heard everything that could
be said on asm.js. Very well written.

------
lmm
So Mozilla now believes other browser makers can and will optimize "generic"
javascript well enough to match the performance of their own specialized
engine, without implementing any specializations: "To say that asm.js code
will be "unusably slow" on browsers other than Firefox implies that those
other VM devs can't match a level of performance that was shown to be possible
by their peers. That is a ridiculous thing to say given how talented those
devs are, which has been proven countless times."

But two years ago Mozilla's position was "A Dart to JS compiler will never be
"decent" compared to having the Dart VM in the browser."

So what's changed?

~~~
azakai
Got a link to that quote? I don't think I've seen it, interested to see the
context.

Anyhow, a lot has changed in two years. dart2js now produces JS that, at least
on the benchmarks on the Dart perf site, compare well with handwritten JS.
This was not obviously possible two years ago! In fact back then I would also
have been extremely skeptical that C++ compiled to JS would get close to
native speed as well, but it has.

~~~
lmm
It was from here;
[https://news.ycombinator.com/item?id=2982256](https://news.ycombinator.com/item?id=2982256)
. Possibly not the best example but I was looking for something I could find
quickly that was representative of the mozilla position as I remembered it.

~~~
azakai
Not sure where to look, there is a lot of stuff there: In the HN comments? The
linked-to blogpost? Or comments in the linked-to blogpost? I skimmed them
quickly, but didn't see what you are quoting yet.

------
z3phyr
One qeustion I would like to ask,

Are asm.js and parallel javascript a competing replacements for C/C++ ?

C++ compilers get faster too, _and leverage even more opportunity for the
programmer to optimise hard, very hard_. On top of that, programmers can
leverage SIMD instructions for even more CPU bound optimisations, and use
technology like C++AMP or openCL for computing effitiently on multicore GPU's.

Could any asm.js program ever be faster than a hand tuned C++ program ?

~~~
Pitarou
I think you're missing the point. asm.js does not compete with languages like
C++: it complements them.

The traditional toolchain (greatly simplified) looks something like this:

    
    
      high-level language -> low-level language -> native code
    

asm.js is a new low-level language that extends this toolchain into the
browser runtime.

~~~
pjmlp
The compilers I use usually do

    
    
        high-level language -> native code
    

Unless you mean compiler IR as low-level language.

~~~
Pitarou
Less pedantry, please.

I told z3phyr enough to understand the role of asm.js. I'm sure z3phyr is
smart enough to appreciate that my one-sentence summary is not the last word
on compiler toolchains.

~~~
z3phyr
Yes, I understood allmost all of it :)

------
sfjailbird
Great writeup and I appreciate the shoutout to GWT, with all the Java hate
many people miss what an amazing piece of technology that is.

------
ksec
Hopefully they dont stop at being only 50% of C Speed.

So asm.js, will be what Java was originally, write once run ( nearly )
everywhere. asm.js being the bytecode of JVM.

Would that also means asm.js essentially open source your code? Are there
anyway to protect it like JVM bytecode or are Mozilla not interested in this.

Would IonMonkey, the whole JS Engine be available as a standalone product like
JVM was?

~~~
azakai
> Would that also means asm.js essentially open source your code? Are there
> anyway to protect it like JVM bytecode or are Mozilla not interested in
> this.

asm.js is JavaScript, so it can be protected like all JavaScript, through
minification and obfuscation. There is no intentional obfuscation in
Emscripten, but in an optimized build we do minify aggressively to reduce code
size, exactly like other minified code on the web.

------
comex
A few points as an outsider about how asm.js could be considered a new VM:

\- PNaCl is different from a true "plugin technology" by being built into the
browser, open, etc. Although browser vendors are not likely to stop competing
on JavaScript speed, in a world where PNaCl is the "correct way" to run C/C++
code, C/C++ compiled to JavaScript will become far less important to optimize
compared to hand-written, dynamic JavaScript: although of course there is
overlap, the priorities are fairly different.

\- For optimum performance, some sort of ahead-of-time compilation is
absolutely required. Although a "sufficiently smart compiler" might include
ahead-of-time compilation for functions whose types are statically known or
speculative specialized compilation in general, I do not think any JS engine
currently does that or will do that soon, so in practice you're talking about
a separate code path for asm.js. Not even close to the size of something like
NaCl, but there.

\- Similarly, I have heard claims that a custom parser provides a significant
speedup, and it's listed as a future project for OdinMonkey. This is probably
only a tiny bit of code, but it also requires an explicit commitment to
asm.js.

\- 50% C speed is not enough - I think everyone would like this to approach
100%. Although I don't think OdinMonkey currently does this, there would
probably be a speedup by using virtual memory tricks - either reserving 4GB of
address space for the heap to avoid having to explicitly check the validity of
an array index, or doing something similar to NaCl, plus possibly even trying
to detect and convert pointer-like integer arguments to real pointers. I think
this is a good thing and should happen, but it very much falls into the
territory of custom asm.js VM.

\- You might also get a performance increase by just replacing the optimizing
compiler wholesale with LLVM? I don't know if this would actually yield a
significant improvement, because a lot of the advanced optimizations would
have already happened at an IR level in emscripten, and I suppose browser
makers would be likely to incorporate whatever improvements into their JS
engines rather than actually adopting LLVM, but I'm not sure I'd rule it
completely out...

\- Some proposed JavaScript features are really mostly useful only for asm.js:
multi-threaded access to ArrayBuffers plus locks (and there's no way asm.js
can be competitive without that); function futures; GC hooks for JVM->asm.js.

\- And some that, while generally useful in some cases, feel aimed towards
asm.js: BinaryData, value objects, SIMD (ala Dart, not Intel's high level
stuff).

~~~
kevingadd
AOT compilation really isn't required; sometimes JIT compilation is a real
winner (like in those startup time cases Alon mentioned, but also in cases
with constrained memory, like mobile) - sometimes 90% of the code in your app
isn't going to be running most of the time, and it's much better to have 1-2ms
pauses for things to be JITted or larger pauses behind a loading screen.

The AOT compilation for asm.js is arguably a win primarily because it produces
deterministic behavior (existing heuristics in SpiderMonkey and V8 are an
ENORMOUS PAIN) and because it enabled them to get their existing IonMonkey
code generator to produce better output. Those both justify the effort, I
think, especially given how cheap it was to implement.

All of those proposed features in your last two bullet points are useful for
JSIL, which does not use asm.js. I can understand how people with a narrow
understanding of JS look at these things and think 'these are all VM features
for asm.js disguised as JS APIs!' because they don't understand, but they
simply aren't. IIRC, Emscripten doesn't even benefit from Binary Data or Value
Objects because it already has a virtual heap; that's not going to change.

~~~
ori_b
With constrained memory, ahead of time wins by a long shot thanks to demand
paging. You only need to allocate physical memory for code that is actually
hit.

With JIT code, you need to allocate space for the bytecode, allocate space for
the linking, relocations, or whatever substitute you use (since bytecode
typically isn't prelinked), allocate space for the JIT itself, and allocate
space for the JITted output.

~~~
kevingadd
Sorry, I should be clearer - the kind of AOT compiles that OdinMonkey
currently does do not benefit from demand paging, because the entire app is
compiled from scratch at startup each time. If it generated executables on
disk, then you could demand-page them in, just like the output from a
traditional compiler. But I don't know if that has been proposed anywhere.

I guess you could allocate guard pages for each function in the application
and AOT-compile each function once on demand to simulate demand paging? Hm.

------
niutech
Here is a community list of projects using asm.js:
[https://github.com/dherman/asm.js/wiki/Projects-using-
asm.js](https://github.com/dherman/asm.js/wiki/Projects-using-asm.js)

------
corresation
This is a fantastic read, and is written in a very readable manner. Thanks.

~~~
MatthewPhillips
azakai is one of the best developers the web community is lucky enough to
have. He also happens to be very articulate.

~~~
slacka
I am no fan of the way CSS, Javascript, and DOM have evolved into HTML5. It
seems Alon not only sees these problems too, he's finding solutions to them by
working around limitations and politics of the WHATWG and W3C.

Mozilla really lucked out with him. I hope they are giving the resources he
needs to keep this up.

