cgmemmgr: CodeModel-aware memory management#60915
cgmemmgr: CodeModel-aware memory management#60915xal-0 wants to merge 12 commits intoJuliaLang:masterfrom
Conversation
73c4991 to
d19dd1a
Compare
02a49e6 to
7b7d65a
Compare
|
We should look into upstreaming this |
9a88404 to
0d6d4d4
Compare
0d6d4d4 to
888e8ad
Compare
| # endif | ||
| # ifdef MAP_NORESERVE | ||
| flags |= MAP_NORESERVE; | ||
| # endif |
There was a problem hiding this comment.
might be worth adding MAP_FIXED_NOREPLACE too, where that exists (Linux mainly, though treated as equivalent to MAP_FIXED in 4.17 to 4.19 by accident)
| }; | ||
| // Until Win10+, we'll put the allocation wherever. | ||
| (void)addr; | ||
| void *ret = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); |
There was a problem hiding this comment.
Why aren't we mimicking the mmap API and passing the hint here too?
There was a problem hiding this comment.
To work around not having MEM_RESERVE_PLACEHOLDER until we bump the minimum Windows version, I have map_reserve return 0. CodeAllocator::map_blocks still calls map_rw with a non-zero address (it takes the 0 from map_reserve and adds the size of the RX region), so I'd have to ifdef that in two places instead.
| #ifdef _OS_WINDOWS_ | ||
| // Noop: we can do better when we bump the minimum OS version to Windows 10, | ||
| // where we can use VirtualAlloc2 with MEM_RESERVE_PLACEHOLDER and | ||
| // MemExtendedParameterAddressRequirements. |
There was a problem hiding this comment.
Wow, an API to do exactly this feature, that looks very nice to have MemExtendedParameterAddressRequirements
As described in #60245, we're unable to use the optimized memory manager on architectures where the default CodeModel is not
Large. Sincemmap()will generally put new mappings close to each other, allocations will succeed until the address space becomes fragmented enough that an RW allocation lands sufficiently far from the corresponding RX allocation, such that a relocation in the code fails.This PR implements a new
JLJITLinkMemoryManager, which is intended to have lower memory use thanorc::MapperJITLinkMemoryManagerand support non-large code models, unlike the old Julia CG memory manager. We accomplish this by reserving a block in the address space that is smaller than the maximum distance for relocations on the current architecture, putting the code and data sections inside this block:We make allocations inside the RX and RW regions (read-only data goes into the RX region for compactness) until one or the other is full, then we unmap unused pages and make a new block elsewhere. The size of a block can be set with
JULIA_CGMEM_BLOCK_SIZE, while the ratio of RX to RW within the block is fixed, based on empirical measurements. If an allocation requires more space than is available in a single block, contiguous pages are allocated at an arbitrary address for it.TODOs:
ROBlockMappersAdd aStill want to do this, but can do it later.ProtectionKeyMapperthat usesMAP_JITon macOS and pkeys on linux.