Hacker News new | past | comments | ask | show | jobs | submit login
What asm.js is and isn't (mozakai.blogspot.com)
167 points by shardling on June 20, 2013 | hide | past | favorite | 49 comments



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.


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


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).


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.


This has already happened years ago. Getting optimal performance in V8, SpiderMonkey and other runtimes is only possible if you hit the sweet spot for the engine's various heuristics. There are literally thousands of different ways to hit 'optimization bailouts' in a modern JS runtime and end up dropped into an interpreter or incredibly slow 'safe mode' JIT, where you will see performance penalties of 10-200x (yes, really).

Plus these heuristics aren't documented, change frequently, and sometimes have bugs. It's awesome.

In this regard, asm.js is an improvement because at least it makes it clear how you end up in the 'fast zone' and it has an offline validator you can use to check your code.


> 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?

Sadly, no. Browsers have an eternal backward compatibility requirement with existing sites, so JavaScript as a directly written language seems unlikely to ever die.

On the bright side, efforts like this make it increasingly feasible to write code in languages that don't have to deal with a dozen quirky runtime implementations. Even if you prefer JavaScript, you might soon be able to use a translator that emulates a single consistent fully-featured implementation of the latest ECMA spec on top of whatever crazy substrate the browser provides.


People still choose to write desktop apps in Java, Python, C# and others despite the existence of C++. Most types of apps do not need the optimizations asm.js allows. Hand-written JavaScript will continue to get faster.


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?


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).


`ndisasm your_binary | less` done!


Won't C/C++ developers choose to just write inline assembly since it can be faster? Sure, but that's doing things the hard way.


If we don't standardize a subset of JavaScript that browsers can execute quicker, it will cause a decline in the use of websites as developers choose to write native apps instead. Then we will lose all the benefits that the Web provides.


Good, this is exactly what I hope happens. Javascript is a ridiculous language to be the only choice for web programming. Also, as more and more code has to be ran client side, how can I protect my investment for the code I need to not be so easily copy-able?


How do you expect DOM to be accessed from C++? Do you think it is possible to make an asm.js -> C++ code map for debugging? Or in worse case asm.js -> C++ (somehow) -> Scala debugging?


I think you'll see even more use of js to optimized js transformers like closure.


Worth reading the whole way through.


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


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?


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.


It was from here; 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.


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.


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 ?


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.


The compilers I use usually do

    high-level language -> native code
Unless you mean compiler IR as low-level language.


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.


Yes, I understood allmost all of it :)


Faire enough, sorry about that.


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.


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?


> 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.


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).


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.


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.


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.


Emscripten certainly should benefit from value objects because they are required to deal with 64-bit integers and 32-bit floats efficiently.

Supporting asm.js as a compilation target for managed languages is very much a goal (according to the FAQ anyway), including binary data and somehow garbage collecting the same within asm.js. I think this includes JSIL eventually, but it doesn't really matter whether you call it asm.js or not: those features fall under the general umbrella of things that are only necessary for compiling high performance, statically typed code to JavaScript, which would become a fairly unimportant use case if the "correct way" to run such code was via PNaCl; thus, they can be considered a parallel technology stack to PNaCl. I personally think that since it's still a way smaller stack and for other reasons, JavaScript is the better approach, but I don't agree that this is all stuff that is orthogonal or going to be done anyway.


> in a world where PNaCl is the "correct way" to run C/C++ code

PNaCl will never be the correct way to run C/C++, because it will never be standardized. The implementation itself defines what it is, it will never have a spec, as it depends on LLVM. Writing a spec for the standardization of PNaCl means you have to also write a spec for LLVM. It will never happen and the only browser that will support it will be Chrome. And unless Chrome wins a monopoly on web browsers, PNaCl will never be part of the web.

It also baffles me that people don't remember what happened with IExplorer and ActiveX. Are people here so young as to haven't lived the early 2000?

What makes PNaCl different from ActiveX anyway? Is it because of the Google branding? Microsoft was once considered to be cool you know. And IExplorer 5 was a kickass browser for its time. Is it because PNaCl has source-code? That doesn't warm me much. Mozilla and other browser vendors could have reversed engineered ActiveX. So what makes them so different that this time it's OK?

> 50% C speed is not enough

We managed to live just fine without C/C++ on the web. We could continue living without it for a very long time. What do you think is better, running C code at 50% speed, or not being able to run C code at all? And people have been using and running with languages that run at 2% of C. Achieving 50% of C, assuming it is true, is sensational considering the benefits (like extreme portability).


"What makes PNaCl different from ActiveX anyway?" It's secure and portable.


Also the code is open source, isn't it?


Maybe it won't be standardized. And maybe websites will start instructing users to use Chrome, or simply publish to the Chrome Web Store. If asm.js takes off, I think it will work, but right now it's one browser maker competing against a kit which provides 90% speed, today, with multithreading and a real debugger, and which, despite its flaws, seems cleaner and saner to many developers (I'm sure you've seen the many kneejerk reactions to JavaScript-as-bytecode), never mind other browser makers which seem fine with none-of-the-above (remember, today, if you even want to use WebGL, you're asking a significant portion of users to switch browser). So despite the hype, I'm not sure asm.js will receive enough support in the next few years to succeed.


The difference between asm.js and PNaCL is that asm.js doesn't need to receive support for it to succeed - asm.js code will get faster and faster, even if browser vendors do not make any effort to support it, virtue of it being a subset of Javascript.

> today, if you even want to use WebGL, you're asking a significant portion of users to switch browser

That's not really true. WebGL is supported in Firefox, Chrome, Opera and Safari. For IExplorer there's a browser plugin available that can add the necessary support.

Of course, having to install a browser plugin for IExplorer is not ideal. Microsoft decided to wait before implementing it for IExplorer versions 9 and 10 due to valid security concerns [1]. Even so, IExplorer 11 may include such support if the Windows 8.1 preview is to be believed.

> I'm sure you've seen the many kneejerk reactions to JavaScript-as-bytecode

I haven't read a single knee-jerk reaction that was informed and justified. The only anti-reaction I've read so far has been from Vyacheslav Egorov, a Google engineer, that's arguing that asm.js is not needed because we haven't reached the limit of where we can take Javascript in terms of performance and that in his opinion it can fragment the web if browser vendors concentrate on optimizing just the asm.js subset, instead of Javascript as a whole.

However, the same arguments can be said about PNaCl. Even inside Google people have mixed opinions about Javascript versus PNaCl and Dart.

> a kit which provides 90% speed, today, with multithreading and a real debugger, and which, despite its flaws, seems cleaner and saner to many developers

I hope you're thinking of something else other than GDB, because if that's the sane debugger you're talking about, then I'll take Firebug any day of the week, thanks ;-)

Javascript does have multithreading by means of web workers, available even in IExplorer since version 10.

Also, lets assume for the sake of the conversation that in general developers really do consider PNaCl to be saner, even though I doubt it. Well, guess what - the resulting apps are not web apps. So why target Chrome with PNaCl, when develpers could be building native apps instead with real native experience? The reasons one wouldn't want to go native have to do with the inherent advantages of the open web. And PNaCl has none of them.

[1] http://blogs.technet.com/b/srd/archive/2011/06/16/webgl-cons...

[2] http://mrale.ph/blog/2013/03/28/why-asmjs-bothers-me.html


> You might also get a performance increase by just replacing the optimizing compiler wholesale with LLVM?

I can't speak directly to this, but I'm sure if it was worth it, the Spidermonkey and V8 teams would have done it already.


It is very hard to do, and LLVM has been difficult to use as a JIT in past projects (Unladen Swallow, for example).

However, Apple is experimenting with this in their FTL (fourth tier LLVM-based) JIT project in JSC. Because Apple drives both JSC and LLVM, this has the highest chance of success of any similar project, I believe, so it is very interesting to watch.


I doubt it. Such a replacement would be a huge effort to write (including integrating it with the existing VM) and maintain, and there are also political factors. Despite those, I don't think it's out of the question that it will happen some day, especially as Chrome already has a copy of LLVM, though I do think it's less relevant than the other stuff I mentioned.

edit: azakai has a better answer :)


Sure it definitely would be a lot to implement _now_, but llvm was released roughly 5 years before v8. The v8 team totally could have chosen it for a compiler back end (code generation). My observation was simply that they didn't, and I believe there probably was a reason for it (though I can't speak to it).

In hindsight, it probably would've made more sense for Google to utilize llvm as a compiler IR in v8 than as a virtual machine as in PNaCl. [1]

[1] http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-October/0437...


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


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


Thorough and on-topic, casual but not jokey. Awesome.


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


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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: