Avoid virtual memory range collision between JIT and emulated RAM.
Passing MAP_FIXED to mmap causes already mapped pages in the requested region to be replaced. On Mac OS X this caused pages for JIT-generatd code to appear in the memory range previously auto-allocated for the RAM of the emulated machine. This led to a hang at boot time. The same problem can probably occur on FreeBSD, but not on Linux since MAP_32BIT is used there instead of MAP_FIXED. The solution is to not use MAP_FIXED, but instead rely on the OS honoring the hinted address which is below 4 GB: we don't need an exact match, just a low address.
This commit is contained in:
parent
933d2dde42
commit
29865e6366
|
@ -43,18 +43,20 @@ void* AllocateExecutableMemory(size_t size, bool low)
|
|||
#else
|
||||
static char *map_hint = 0;
|
||||
#if defined(__x86_64__) && !defined(MAP_32BIT)
|
||||
// This OS has no flag to enforce allocation below the 4 GB boundary,
|
||||
// but if we hint that we want a low address it is very likely we will
|
||||
// get one.
|
||||
// An older version of this code used MAP_FIXED, but that has the side
|
||||
// effect of discarding already mapped pages that happen to be in the
|
||||
// requested virtual memory range (such as the emulated RAM, sometimes).
|
||||
if (low && (!map_hint))
|
||||
map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */
|
||||
#endif
|
||||
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANON | MAP_PRIVATE
|
||||
#if defined(__x86_64__)
|
||||
#if defined(MAP_32BIT)
|
||||
#if defined(__x86_64__) && defined(MAP_32BIT)
|
||||
| (low ? MAP_32BIT : 0)
|
||||
#else
|
||||
| (low ? MAP_FIXED : 0)
|
||||
#endif /* defined(MAP_32BIT) */
|
||||
#endif /* defined(__x86_64__) */
|
||||
#endif
|
||||
, -1, 0);
|
||||
#endif /* defined(_WIN32) */
|
||||
|
||||
|
|
Loading…
Reference in New Issue