Request For Comments: switching/resizing heaps in asm.js

Minor update: builtin calls cannot reenter so they are fine to use in index/rhs expressions. (The initial landing in FF has a bug, putting the “can call” check in the wrong place which ruled out coerced builtin calls.) If this exception causes any trouble, though, we can just be conservative and rule out all calls, builtin or not.

I think it makes sense to allow builtin calls.

Update: while this feature works without issue or slowdown in FF/Edge, the change-heap function interferes with the generic closure analysis that allows V8/JSC to detect and optimize the immutability of the heap view variables [1]. In V8, this causes a drastic performance penalty (see issue 3907). If that was the end of the story, I think it’d make sense to hold out until optimizations improve (e.g., on V8 is planning to do full asm.js optimizations). However, WebAssembly will have a simpler and more direct form of resizing along with cross-browser support. Due to the above V8 issue, I don’t think many people are using asm.js heap resizing (ALLOW_MEMORY_GROWTH is off by default in Emscripten and recommended against), so to simplify engines, I’d like to remove support for the change-heap function from SpiderMonkey and have suggested to Chakra folks that they do the same. Of course, Emscripten can still support ALLOW_MEMORY_GROWTH by simply emitting almost-but-not-asm.js.

Here’s the bugzilla bug for its removal.

I will open an issue on Chakra once we go open source this month.

In the early phases of WASM support, as I understand it there will be an asm.js-based polyfill. Since asm.js will not support resizing heaps but WASM will, does this mean the polyfill will either:

  • work with a fixed-size heap, and crash if it goes over (creating a portability problem), or
  • omit “use asm”, running considerably slower than a normal asm.js build, possibly removing some incentive to use WASM instead?

Or is there another plan to work around this?

I think the options you outlined are basically all we can do, yeah. The second (omit “use asm”) seems better to me, although it might be an option in the polyfill or different polyfills might do different things. Overall I don’t think this removes an incentive to use wasm (shipping as wasm allows running as wasm natively, which is strictly better, except for the time to polyfill if it isn’t), but maybe I’m not seeing something?

But in general, polyfilling has not been a strong constraint on the design of wasm. This means that wasm is less limited by legacy, but it also means that polyfilling will not be perfect. Aside from resizing memory, there are issues with numeric corner cases (trapping vs not), statements=expressions code sometimes being inefficient to translate to JS, and others. Polyfilling will still work, but it will require some caution I think.

I guess that’s a reasonable view of polyfilling, yeah. Hopefully use of the polyfill will be transient anyway and vendors will support WASM before long!