Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/coreclr/pal/src/include/pal/virtual.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,24 @@ class ExecutableMemoryAllocator
int32_t GenerateRandomStartOffset();

private:

// There does not seem to be an easy way find the size of a library on Unix.
// So this constant represents an approximation of the libcoreclr size (on debug build)
// So this constant represents an approximation of the libcoreclr size
// that can be used to calculate an approximate location of the memory that
// is in 2GB range from the coreclr library. In addition, having precise size of libcoreclr
// is not necessary for the calculations.
static const int32_t CoreClrLibrarySize = 100 * 1024 * 1024;
static const int32_t CoreClrLibrarySize = 16 * 1024 * 1024;

// This constant represent the max size of the virtual memory that this allocator
// will try to reserve during initialization. We want all JIT-ed code and the
// entire libcoreclr to be located in a 2GB range.
// entire libcoreclr to be located in a 2GB range on x86
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
// It seems to be more difficult to reserve a 2Gb chunk on arm so we'll try smaller one
static const int32_t MaxExecutableMemorySize = 1024 * 1024 * 1024;
#else
static const int32_t MaxExecutableMemorySize = 0x7FFF0000;
#endif

static const int32_t MaxExecutableMemorySizeNearCoreClr = MaxExecutableMemorySize - CoreClrLibrarySize;

// Start address of the reserved virtual address space
Expand Down
24 changes: 19 additions & 5 deletions src/coreclr/pal/src/map/virtual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2140,7 +2140,15 @@ void ExecutableMemoryAllocator::TryReserveInitialMemory()
int32_t preferredStartAddressIncrement;
UINT_PTR preferredStartAddress;
UINT_PTR coreclrLoadAddress;
const int32_t MemoryProbingIncrement = 128 * 1024 * 1024;

#if defined(TARGET_ARM) || defined(TARGET_ARM64)
// Smaller steps on ARM because we try hard finding a spare memory in a 128Mb
// distance from coreclr so e.g. all calls from corelib to coreclr could use relocs
const int32_t AddressProbingIncrement = 8 * 1024 * 1024;
#else
const int32_t AddressProbingIncrement = 128 * 1024 * 1024;
#endif
const int32_t SizeProbingDecrement = 128 * 1024 * 1024;

// Try to find and reserve an available region of virtual memory that is located
// within 2GB range (defined by the MaxExecutableMemorySizeNearCoreClr constant) from the
Expand All @@ -2161,12 +2169,18 @@ void ExecutableMemoryAllocator::TryReserveInitialMemory()
{
// Try to allocate above the location of libcoreclr
preferredStartAddress = coreclrLoadAddress + CoreClrLibrarySize;
preferredStartAddressIncrement = MemoryProbingIncrement;
preferredStartAddressIncrement = AddressProbingIncrement;
}
else
{
// Try to allocate below the location of libcoreclr
preferredStartAddress = coreclrLoadAddress - MaxExecutableMemorySizeNearCoreClr;
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
// For arm for the "high address" case it only makes sense to try to reserve 128Mb
// and if it doesn't work - we'll reserve a full-sized region in a random location
sizeOfAllocation = SizeProbingDecrement;
#endif

preferredStartAddress = coreclrLoadAddress - sizeOfAllocation;
preferredStartAddressIncrement = 0;
}

Expand All @@ -2180,10 +2194,10 @@ void ExecutableMemoryAllocator::TryReserveInitialMemory()
}

// Try to allocate a smaller region
sizeOfAllocation -= MemoryProbingIncrement;
sizeOfAllocation -= SizeProbingDecrement;
preferredStartAddress += preferredStartAddressIncrement;

} while (sizeOfAllocation >= MemoryProbingIncrement);
} while (sizeOfAllocation >= SizeProbingDecrement);

if (m_startAddress == nullptr)
{
Expand Down