- 4 minutes read

The day after I finished my article claiming Javascript to be the new assembler language I heard about the asm.js project. This project strongly supports my previous article's theory. Even the project's name alleges asm.js programs are sort of assembler programs.

The goal of asm.js is to define a subset of Javascript that can be executed very efficiently. The idea is to identify expensive operations and to replace them with cheaper ones. But there's a catch: you don't really want to write an asm.js program. It looks a little weird, and it's requires a lot of additional key strokes ordinary Javascript doesn't require. So why should we bother?

If you'd rather not generate asm.js code you still may generate it. And that's the way it's meant. Asm.js code is meant to be the result of a cross-compiler. For example, you can use Emscripten to generate asm.js code from C or C++ source code.

The interesting thing is asm.js programs don't execute faster automatically. Quite the contrary, they run slower than ordinary Javascript programs as they are more complicated. For instance, the asm.js project identified the dynamic type system as a major obstacle to performance. They want to provide hints to the Javascript interpreter to make it clear which type is used. So every integer operation is followed by an "| 0" to coerce the result to an integer like so:

function add1(x) { x = x|0; // x : int return (x+1)|0; }

The second line shows another hint: the function parameter is defined as an integer parameter by the line "x = x | 0:" which does nothing at all in standard Javascript. If x were a floating point parameter, we'd have to indicate this by

function add1(x) { x = +x;

Again, this doesn't change anything at all in standard Javascript.

So why should we add such a line?

At first glance, it's useless. It doesn't make your Javascript program faster. It even slows it down.

Unless you've got a Javascript interpreter aware of asm.js. This is a Mozilla project, so it shouldn't surprise you Firefox already supports asm.js code. Google is interested in the project, so chances are Google Chrome also contains asm.js support. They already added some limited asm.js support in their browser, yielding a performance boost of 240%.

But wait. How can adding additional lines of code make a program faster?

The basic idea is that browser can safely rely on certain assumptions when executing a asm.js program. Asm.js is defined in a way that programs can be compiled ahead of time and variables are statically typed (which allows for better performance optimizations). To facilitate the detection of asm.js code you have to add a prologue directive to each function:

function MyAsmModule() { "use asm"; // module body }

Modern Javascript engines use a Just In Time compiler instead of a traditional interpreter. Using a JIT basically amounts to caching the machine code already executed. Dynamically typed programming languages are difficult challenges to JIT compilers because variable types can change - and this forces the JIT compiler to invalidate the machine code in cache. In contrast, an Ahead Of Time compiler can compile a program during load time. Thanks to the hints it never has to invalidate the code. It doesn't have to add code to detect variable type changes. It simply relies the type never changes. This makes for high execution speed.

Conclusion

Ecmascript 5, Ecmascript 6, Dart, Ceylon, Kotlin, asm.js - there are a lot of interesting developments going on in the Javascript community. Asm.js is particularly interesting because it's creators claim asm.js code runs only 50% slower than C++ code. If they succeed in convincing the majority of browser producers to support asm.js, the project may have a major impact in the industry.

What's coming next?

It largely depends on the browser manufacturers future actions - and of course on how the community reacts. If Mozilla manages to convince Google to add asm.js support to Chrome, chances are asm.js is going to have a major impact in the industry. Developers might adopt languages like Dart, Kotlin, Ceylon and the like to make use of an advances programming model while still targeting at the browser.

If this happens, Javascript even might become replaced by another language. A native Dart VM already exists. It should be a easy for Google to include the Dart VM in their browser and to compile to Dart code instead of compiling to Javascript code. With Chrome's growing market share they may be able to establish Dart as the second language in the web.


http://ejohn.org/blog/asmjs-javascript-compile-target/

The asm.js project


Comments