Large Pages on Linux & macOS (#24098)
authorMukul Sabharwal <muks@microsoft.com>
Fri, 19 Apr 2019 21:54:35 +0000 (14:54 -0700)
committerMaoni Stephens <Maoni0@users.noreply.github.com>
Fri, 19 Apr 2019 21:54:35 +0000 (14:54 -0700)
src/gc/unix/config.h.in
src/gc/unix/configure.cmake
src/gc/unix/gcenv.unix.cpp
src/pal/src/config.h.in
src/pal/src/configure.cmake
src/pal/src/map/virtual.cpp

index 99866cd..7f4d8d7 100644 (file)
@@ -9,6 +9,7 @@
 #cmakedefine01 HAVE_SYS_MMAN_H
 #cmakedefine01 HAVE_PTHREAD_THREADID_NP
 #cmakedefine01 HAVE_PTHREAD_GETTHREADID_NP
+#cmakedefine01 HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY
 #cmakedefine01 HAVE_MAP_HUGETLB
 #cmakedefine01 HAVE_SCHED_GETCPU
 #cmakedefine01 HAVE_NUMA_H
index 2e31766..3e478c4 100644 (file)
@@ -29,6 +29,15 @@ check_cxx_source_compiles("
 
     int main()
     {
+        return VM_FLAGS_SUPERPAGE_SIZE_ANY;
+    }
+    " HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY)
+
+check_cxx_source_compiles("
+    #include <sys/mman.h>
+
+    int main()
+    {
         return MAP_HUGETLB;
     }
     " HAVE_MAP_HUGETLB)
index edddee1..c248082 100644 (file)
@@ -551,6 +551,8 @@ void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size)
 {
 #if HAVE_MAP_HUGETLB
     uint32_t largePagesFlag = MAP_HUGETLB;
+#elif HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY
+    uint32_t largePagesFlag = VM_FLAGS_SUPERPAGE_SIZE_ANY;
 #else
     uint32_t largePagesFlag = 0;
 #endif
index d0e14df..3ceb180 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _PAL_CONFIG_H_INCLUDED
 #define _PAL_CONFIG_H_INCLUDED 1
 
+#cmakedefine01 HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY
+#cmakedefine01 HAVE_MAP_HUGETLB
 #cmakedefine01 HAVE_IEEEFP_H
 #cmakedefine01 HAVE_SYS_VMPARAM_H
 #cmakedefine01 HAVE_MACH_VM_TYPES_H
index a4d550e..a991e75 100644 (file)
@@ -45,6 +45,22 @@ endif()
 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
 
 check_cxx_source_compiles("
+#include <sys/mman.h>
+int main()
+{
+  return VM_FLAGS_SUPERPAGE_SIZE_ANY;
+}
+" HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY)
+
+check_cxx_source_compiles("
+#include <sys/mman.h>
+int main()
+{
+  return MAP_HUGETLB;
+}
+" HAVE_MAP_HUGETLB)
+
+check_cxx_source_compiles("
 #include <lttng/tracepoint.h>
 int main(int argc, char **argv) {
   return 0;
index 4dae9f3..ff5cde9 100644 (file)
@@ -70,7 +70,8 @@ Function:
 static LPVOID ReserveVirtualMemory(
                 IN CPalThread *pthrCurrent, /* Currently executing thread */
                 IN LPVOID lpAddress,        /* Region to reserve or commit */
-                IN SIZE_T dwSize);          /* Size of Region */
+                IN SIZE_T dwSize,           /* Size of Region */
+                IN DWORD fAllocationType);  /* Allocation Type */
 
 
 // A memory allocator that allocates memory from a pre-reserved region
@@ -915,7 +916,7 @@ static LPVOID VIRTUALReserveMemory(
     if (pRetVal == NULL)
     {
         // Try to reserve memory from the OS
-        pRetVal = ReserveVirtualMemory(pthrCurrent, (LPVOID)StartBoundary, MemSize);
+        pRetVal = ReserveVirtualMemory(pthrCurrent, (LPVOID)StartBoundary, MemSize, flAllocationType);
     }
 
     if (pRetVal != NULL)
@@ -958,7 +959,8 @@ static LPVOID VIRTUALReserveMemory(
 static LPVOID ReserveVirtualMemory(
                 IN CPalThread *pthrCurrent, /* Currently executing thread */
                 IN LPVOID lpAddress,        /* Region to reserve or commit */
-                IN SIZE_T dwSize)           /* Size of Region */
+                IN SIZE_T dwSize,           /* Size of Region */
+                IN DWORD fAllocationType)   /* Allocation type */
 {
     UINT_PTR StartBoundary = (UINT_PTR)lpAddress;
     SIZE_T MemSize = dwSize;
@@ -986,6 +988,19 @@ static LPVOID ReserveVirtualMemory(
     mmapFlags |= MAP_FIXED;
 #endif // HAVE_VM_ALLOCATE
 
+    if ((fAllocationType & MEM_LARGE_PAGES) != 0)
+    {
+#if HAVE_MAP_HUGETLB
+        mmapFlags |= MAP_HUGETLB;
+        TRACE("MAP_HUGETLB flag set\n");
+#elif HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY
+        mmapFlags |= VM_FLAGS_SUPERPAGE_SIZE_ANY;
+        TRACE("VM_FLAGS_SUPERPAGE_SIZE_ANY flag set\n");
+#else
+        TRACE("Large Pages requested, but not supported in this PAL configuration\n");
+#endif
+    }
+
     mmapFlags |= MAP_ANON | MAP_PRIVATE;
 
     LPVOID pRetVal = mmap((LPVOID) StartBoundary,
@@ -1338,10 +1353,10 @@ VirtualAlloc(
     }
 
     /* Test for un-supported flags. */
-    if ( ( flAllocationType & ~( MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_TOP_DOWN | MEM_RESERVE_EXECUTABLE ) ) != 0 )
+    if ( ( flAllocationType & ~( MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_TOP_DOWN | MEM_RESERVE_EXECUTABLE | MEM_LARGE_PAGES ) ) != 0 )
     {
         ASSERT( "flAllocationType can be one, or any combination of MEM_COMMIT, \
-               MEM_RESERVE, MEM_TOP_DOWN, or MEM_RESERVE_EXECUTABLE.\n" );
+               MEM_RESERVE, MEM_TOP_DOWN, MEM_RESERVE_EXECUTABLE, or MEM_LARGE_PAGES.\n" );
         pthrCurrent->SetLastError( ERROR_INVALID_PARAMETER );
         goto done;
     }
@@ -2145,7 +2160,7 @@ void ExecutableMemoryAllocator::TryReserveInitialMemory()
     // Do actual memory reservation.
     do
     {
-        m_startAddress = ReserveVirtualMemory(pthrCurrent, (void*)preferredStartAddress, sizeOfAllocation);
+        m_startAddress = ReserveVirtualMemory(pthrCurrent, (void*)preferredStartAddress, sizeOfAllocation, 0 /* fAllocationType */);
         if (m_startAddress != nullptr)
         {
             break;
@@ -2175,7 +2190,7 @@ void ExecutableMemoryAllocator::TryReserveInitialMemory()
         //   - The code heap allocator for the JIT can allocate from this address space. Beyond this reservation, one can use
         //     the COMPlus_CodeHeapReserveForJumpStubs environment variable to reserve space for jump stubs.
         sizeOfAllocation = MaxExecutableMemorySize;
-        m_startAddress = ReserveVirtualMemory(pthrCurrent, nullptr, sizeOfAllocation);
+        m_startAddress = ReserveVirtualMemory(pthrCurrent, nullptr, sizeOfAllocation, 0 /* fAllocationType */);
         if (m_startAddress == nullptr)
         {
             return;