Make -vm_size 2G by default for 64-bit
This is part of a series of 64-bit scalability improvements: xref the original reachability issue #774 (closed), splitting vmcode from vmheap #1132 (closed), and W^X #3556 which wants this 2G by default as a pre-req.
The idea is that now we have put all of our reachability-guaranteed code into its own region, we may as well reserve the maximum 2G amount at init time for that region, and avoid having to ever run out of space and spill over onto individual OS allocations and run into complications like #2115.
The complication is that we need client libraries (including extension libraries, but not third-party dependencies loaded by our private loader that do not interact directly with DR) to be inside that same 2G region. So we need to coordinate between DR's VMM and the file mapping done by the private loader. In particular, the VMM wants to reserve 2G up front and then hand a piece of it to the loader to map a file. While this is feasible on UNIX where we can MAP_FIXED on top of an existing mmap, or munmap just a piece of a prior large mmap (though that route has a race), it is not possible on Windows to map a file on top of an existing address space reservation. Nor is it possible to un-reserve just a piece of a reservation: the entire thing must be un-reserved.
Here are some possible solutions for Windows:
-
A) Pick vmcode range but don't reserve it, then load client libs + extensions in reachable spots, then separately reserve all the pieces in the vmcode range not occupied by libs? Would need a list of them to free at exit b/c have to use NtFreeVirtualMemory for the anon and NtUnmapViewOfSection for the files. And this would not work with post-init dr_map_file() with DR_MAP_CACHE_REACHABLE.
-
B) Long-term, abandon client reachability guarantees and DR_MAP_CACHE_REACHABLE?
-
C) Have client libs all in single space at top of 2G region? Might pay in non-preferred-base but this is 64-bit so even Windows libs should be partly PIC w/ fewer relocations. Ideally still load client libs first so don't need a max size. Pack them in from the top, then reserve the rest. Simply stop supporting dr_map_file() with DR_MAP_CACHE_REACHABLE??
-
D) Change Windows to do a separate reservation every, say, 640K? Then have flexibility to make holes in the vmm region. Would a separate call every 64K cost anything in kernel resources? Just extra time for 16M alloc syscalls? Or 160K for every 640K.
-
E) Combine C and D. Only support client libs + DR_MAP_CACHE_REACHABLE in the top 64M of the vmm region. Do one big reservation below that, and for that 64M, do 100 640K reservations, so we support 100 med-or-small files. In the 7.1.0 release, all extensions are <640K; dbghelp is 1.7M; debug drmemorylib is 7.2M (release 2.1M) so it would need 12 of the 100 slots?
-
F) Abandon 2G vmcode size on Windows. Keep it 512M, or 1G and update all preferred bases, by default and keep current search-from-OS code.
I'm going with F as the short-term solution: i.e., only implement 2G vmcode size by default for Linux, using probably MAP_FIXED, and leave it as future work to bring in Windows, even if that future work changes how Linux works as well.