* ahead-of-time compilation and optimization instead of heuristic JIT compilation
* heap access can be made extremely efficient, close to native pointer accesses on most (all? still experimenting) major platforms
* integers and doubles are represented completely unboxed -- no dynamic type guards
* absolutely no GC interaction or pauses
* no JIT guards, bailouts, deoptimizations, etc. necessary
But the bottom line here is: asm.js can be implemented massively faster than anything existing JS engines can do, and it's closing the gap to native more than ever. Not only that, it's significantly easier to implement in an existing JS engine than from-scratch technologies like NaCl/PNaCl. Luke Wagner has implemented our optimizing asm.js engine entirely by himself in the matter of a few months.
As the site says, the spec is a work in progress but it's nearly done. Our prototype implementation in Firefox is almost done and will hopefully land in the coming few months. Alon Zakai is presenting some of the ideas at http://mloc-js.com tomorrow, including an overview of the ideas and some preliminary benchmarks. We'll post his slides afterwards.
As for debugging, the story is the same as Emscripten. I believe there's plenty of work to do to make it better, but it's no different than the existing state of affairs. All we're doing is formalizing existing practice so that engines can capitalize on it and optimize better.
So, for example, you can provide clear hints that value x should be an int32, value y should be a float, etc. And if you create a virtual heap out of a Typed Array, asm.js lets you ensure that the JIT maps uses of that array to direct memory accesses where possible (instead of bounds-checked array lookups).