Move sharedmem GC mark stack to sharedmem
Move sharedmem GC mark stack to sharedmem

Summary:
The sharedmem GC has an incremental mark phase, which runs in the server process
between rechecks. Becuase we only performed marking work in the server process,
the mark stack itself is not shared.

This diff moves the mark stack into shared memory. This move enables the next
diff, which adds to the mark stack from workers. See the next diff for more
about the motivation.

When setting up the mappings, we reserve 256 MiB of address space for the mark
stack, but we only commit the first 4 KiB, and grow by doubling.

Before this diff, we also started with a 4 KiB mark stack, and doubled it as
needed. The biggest difference is that we now do this in a shared memory segment
instead of using malloc/realloc/free.

Another difference is how we track the capacity. Before, we had a seaprate
`mark_stack_size` variable. This diff uses a little "trick" exploiting the
power-of-2 sizes. At any point, we know the capacity of the mark stack is the
next power of 2 number, so we just use `mark_ptr` for both.

(Using a single value simplifies concurrency issues in the next diff.)

Furthermore, we make no attempt to free space in the mark stack after the mark
phase is done. We could introduce APIs to do this (VirtualFree+DECOMMIT on
Windows, fallocate+"punch holes" on Linux), but this does not seem very useful.
If we grew the mark stack to perform collection N, it's pretty likely that we
will need a similarly sized mark stack for collection N+1. And the upper limit
of 256 MiB is not really that much anyway.

Reviewed By: mroch

Differential Revision: D39075055

fbshipit-source-id: 044c0ae969a966615f4078018ccedd6c855a3a25

mroch/flow,facebook/flow,facebook/flow,mroch/flow,facebook/flow,mroch/flow,facebook/flow,facebook/flow,mroch/flow,mroch/flow,facebook/flow,mroch/flow,mroch/flow,facebook/flow