Closed Bug 927182 Opened 11 years ago Closed 11 years ago

asm.js does not support resizing the heap

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 965880

People

(Reporter: caustin, Unassigned)

References

Details

I'm filing this bug in writing because 1) it's a real pain point for us and 2) I've had to explain it multiple times to people inside and outside of Mozilla.

asm.js does not support resizing the heap during execution.  On a traditional platform, the malloc() implementation would, when its internal free lists and such are exhausted, ask the OS for more memory (via mmap, sbrk, whatever).  Because asm.js is backed by an ArrayBuffer and ArrayBuffers cannot be resized, malloc() will instead fail.

"But Emscripten supports requesting a memory resize by dropping entirely out of the asm.js module, recreating the ArrayBuffer, copying the old data over, and relinking the asm.js module with the new ArrayBuffer."

That is a clever workaround, but we would struggle to guarantee that we could predict exactly whenever we were going to exceed our memory budget.  This approach requires too much rigor for me to be confident that we'd catch every case where the heap could grow beyond its capacity.

"But why not just set an upper bound on the heap size and allocate 1 GB up front?"  Our use case is a small-ish 3D engine that you might have open on half a dozen open browser tabs.  The common use case wouldn't require much RAM, and thus I would hate to pay a 1 GB penalty per tab open just in case a single tab might use it.

Ideally we would start each tab at a minimal heap size and grow (or shrink) as necessary to minimize net heap usage on the customer's machine.

I heard that dherman might be working on an ArrayBuffer.resize proposal, but in advance of that, this bug documents our pain point.

Until asm.js supports resizing the heap, we will continue to generate non-asm.js code with Emscripten.

Thanks!
Some relevant discussion is in bug 855669, more focused on decommitting memory than growing, but the growth issues comes up there as well.
Agreed that resize would be really useful.  Indeed, it's already on the "Planned next projects" list:
  https://wiki.mozilla.org/Javascript:SpiderMonkey:OdinMonkey#Planned_next_projects
so hopefully we'll have something you can use before too long.
I agree it's something we want, but I don't follow this argument:

(In reply to Chad Austin from comment #0)
> "But why not just set an upper bound on the heap size and allocate 1 GB up
> front?"  Our use case is a small-ish 3D engine that you might have open on
> half a dozen open browser tabs.  The common use case wouldn't require much
> RAM, and thus I would hate to pay a 1 GB penalty per tab open just in case a
> single tab might use it.

Are you worried about virtual memory space? I would expect that allocating a 1GB ArrayBuffer would only consume about 8KB of memory until you started using more of it. (4KB for the page to hold the first byte, plus 4KB for some AsmJS bookkeeping overhead.) The rest should only consume virtual memory address space, which would only be a problem on 32 bits platforms. Is that the concern?
(In reply to Steve Fink [:sfink] from comment #3)
> I agree it's something we want, but I don't follow this argument:
> 
> (In reply to Chad Austin from comment #0)
> > "But why not just set an upper bound on the heap size and allocate 1 GB up
> > front?"  Our use case is a small-ish 3D engine that you might have open on
> > half a dozen open browser tabs.  The common use case wouldn't require much
> > RAM, and thus I would hate to pay a 1 GB penalty per tab open just in case a
> > single tab might use it.
> 
> Are you worried about virtual memory space? I would expect that allocating a
> 1GB ArrayBuffer would only consume about 8KB of memory until you started
> using more of it. (4KB for the page to hold the first byte, plus 4KB for
> some AsmJS bookkeeping overhead.) The rest should only consume virtual
> memory address space, which would only be a problem on 32 bits platforms. Is
> that the concern?

Allocating a 1GB arraybuffer once in a Firefox process on Windows is enough to completely exhaust address space, committed or not - if you try to allocate a second one, that fails. (I can't tell if the whole thing gets committed when allocated because the browser tries to zero out the memory - hard to be sure). So that definitely isn't a workable solution right now. IIRC Internet Explorer and Chrome have similar limitations based on the last time I tested this, so you wouldn't be able to ship applications that rely on this technique if you wanted them to work in almost any scenario on Windows. That seems like a problem to me, personally.
(In reply to Steve Fink [:sfink] from comment #3)
> Are you worried about virtual memory space? I would expect that allocating a
> 1GB ArrayBuffer would only consume about 8KB of memory until you started
> using more of it. (4KB for the page to hold the first byte, plus 4KB for
> some AsmJS bookkeeping overhead.) The rest should only consume virtual
> memory address space, which would only be a problem on 32 bits platforms. Is
> that the concern?

32-bit browsers are important, yes.

Also, I believe ArrayBuffers are committed address space, on Windows.  Is that not correct?  Does Firefox reserve 1 GB of address space and commit as used?  I see the bug that azakai linked discusses a possible API for decommitting.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.