Skip to content

Commit

Permalink
VM: Better strategy for TryReserveInitialMemory on arm64 (jump stubs) (
Browse files Browse the repository at this point in the history
…#70707)

* Better strategy for ReserveInitialMemory on arm64

* Clean up

* Address feedback

* fix "below" case

* Address feedback

* Update virtual.cpp

* Apply suggestions from code review

Co-authored-by: Jan Vorlicek <jan.vorlicek@volny.cz>

* Address feedback

* Fix defines

* Remove env var

* clean up

* Clean up

* Update virtual.h

Co-authored-by: Jan Vorlicek <jan.vorlicek@volny.cz>
  • Loading branch information
EgorBo and janvorli committed Jun 22, 2022
1 parent 6258ee5 commit 4388cc5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
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

0 comments on commit 4388cc5

Please sign in to comment.