Open Bug 799250 Opened 8 years ago Updated 4 years ago

madvise(MADV_DONTNEED) overdeep stacks


(Core :: JavaScript Engine, defect)

Not set




(Reporter: luke, Unassigned)



(Whiteboard: [Memshrink:P3][slim:?])

On non-Windows platforms, each JSRuntime reserves a 4MB stack via mmap().  While this immediately consumes 4MB of *address space*, the OS won't actually allocate pages (in ram or swap) until the memory is touched.  Most JS uses very little stack (<16KB), however, all it takes is one webpage with a runaway recursion (function f() { f() }), to touch the entire 4MB stack.

The idea for this bug is that, after one of these super-deep calls (after the stack has been popped and the memory is garbage), we could call madvise(MADV_DONTNEED).  This would particularly benefit mobile devices without a swap file.

We already have logic to maintain a high-water mark on Windows (where we MEM_RESERVE eagerly and MEM_COMMIT up to the high-water mark), so we only need to add the ability to occasionally decommit (the only challenge being to define a good "occasionally").

The first step, of course, would be to get some idea of whether this would actually save much memory in practice: how often do we hit a super-deep stack on mobile?  Telemetry could tell us.
> (the only challenge being to define a good "occasionally").

On GC?
That could work, I haven't thought it through though.  E.g.:
 1. how long does it take to madvise()-free 4MB?  Is it fine to do it all at once during GC?
 2. do we need to guard against doing this too frequently?  e.g., let's say you have a script that does a deep recursion on every requestAnimationFrame (perhaps it does a recursive traversal of a big tree), would we need to add a time element to our heuristic to avoid introducing a bunch of needless page faults? (perhaps the faults are cheap enough that we don't care?)

These probably aren't hard problems, just things it would be good to check out.
Whiteboard: [Memshrink] → [Memshrink][slim:?]
Whiteboard: [Memshrink][slim:?] → [Memshrink:P3][slim:?]
Assignee: general → nobody
You need to log in before you can comment on or make changes to this bug.