From 5b5acde8fc23809a68f794db1ecb23bf6a833aed Mon Sep 17 00:00:00 2001 From: Dmitri Pivkine Date: Mon, 30 Oct 2023 13:24:23 -0400 Subject: [PATCH] Use small page size/flags for Sparse Virtual Memory Currently Sparse Virtual Memory uses page size Object Heap is allocated with. We want to use small pages for Sparse Heap always regardless. Also Sparse Virtual Memory uses page flags "requested" for Object Heap. This is the bug. Page flags should be paired with the page size. Please note, that current MM_SparseVirtualMemory implementation can use double mapping instead of off-heap. This is an experimental feature never used in the code and not planned to be used. This feature uses hidden assumption that memory page size/flags should be the same for Object and Sparse heaps. This PR can break it potentially in the case memory page settings in the Object Heap and Sparse heap are different. We are going to be aware about this if we need another round of experimental testing with double mapping support. Signed-off-by: Dmitri Pivkine --- gc/base/GCExtensionsBase.cpp | 8 ++++++++ gc/base/GCExtensionsBase.hpp | 13 +++++++++---- gc/base/SparseVirtualMemory.cpp | 5 +++-- gc/base/SparseVirtualMemory.hpp | 4 ++-- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/gc/base/GCExtensionsBase.cpp b/gc/base/GCExtensionsBase.cpp index 97abfe32715..803321e76fe 100644 --- a/gc/base/GCExtensionsBase.cpp +++ b/gc/base/GCExtensionsBase.cpp @@ -135,6 +135,10 @@ MM_GCExtensionsBase::initialize(MM_EnvironmentBase* env) gcmetadataPageSize = pageSizes[0]; gcmetadataPageFlags = OMRPORT_VMEM_PAGE_FLAG_NOT_USED; + sparseHeapPageSize = pageSizes[0]; + sparseHeapPageFlags = OMRPORT_VMEM_PAGE_FLAG_NOT_USED; + + #define SIXTY_FOUR_KB ((uintptr_t)64 * 1024) #define ONE_MB ((uintptr_t)1 * 1024 * 1024) #define TWO_MB ((uintptr_t)2 * 1024 * 1024) @@ -160,6 +164,10 @@ MM_GCExtensionsBase::initialize(MM_EnvironmentBase* env) gcmetadataPageFlags = pageFlags[0]; } + if (!validateDefaultPageParameters(sparseHeapPageSize, sparseHeapPageFlags, pageSizes, pageFlags)) { + sparseHeapPageSize = pageSizes[0]; + sparseHeapPageFlags = pageFlags[0]; + } if (!_forge.initialize(env->getPortLibrary())) { goto failed; diff --git a/gc/base/GCExtensionsBase.hpp b/gc/base/GCExtensionsBase.hpp index e2c6e9f8fe4..4290a72e440 100644 --- a/gc/base/GCExtensionsBase.hpp +++ b/gc/base/GCExtensionsBase.hpp @@ -281,10 +281,13 @@ class MM_GCExtensionsBase : public MM_BaseVirtual { #endif /* OMR_GC_DOUBLE_MAP_ARRAYLETS */ bool isVirtualLargeObjectHeapRequested; bool isVirtualLargeObjectHeapEnabled; - uintptr_t requestedPageSize; - uintptr_t requestedPageFlags; - uintptr_t gcmetadataPageSize; - uintptr_t gcmetadataPageFlags; + + uintptr_t requestedPageSize; /**< Memory page size for Object Heap */ + uintptr_t requestedPageFlags; /**< Memory page flags for Object Heap */ + uintptr_t gcmetadataPageSize; /**< Memory page size for GC Meta data */ + uintptr_t gcmetadataPageFlags; /**< Memory page flags for GC Meta data */ + uintptr_t sparseHeapPageSize; /**< Memory page size for Sparse Object Heap */ + uintptr_t sparseHeapPageFlags; /**< Memory page flags for Sparse Object Heap */ #if defined(OMR_GC_MODRON_SCAVENGER) MM_SublistPool rememberedSet; @@ -1516,6 +1519,8 @@ class MM_GCExtensionsBase : public MM_BaseVirtual { , requestedPageFlags(OMRPORT_VMEM_PAGE_FLAG_NOT_USED) , gcmetadataPageSize(0) , gcmetadataPageFlags(OMRPORT_VMEM_PAGE_FLAG_NOT_USED) + , sparseHeapPageSize(0) + , sparseHeapPageFlags(OMRPORT_VMEM_PAGE_FLAG_NOT_USED) #if defined(OMR_GC_MODRON_SCAVENGER) , rememberedSet() , oldHeapSizeOnLastGlobalGC(UDATA_MAX) diff --git a/gc/base/SparseVirtualMemory.cpp b/gc/base/SparseVirtualMemory.cpp index 0c83789314a..3af0a1b9d5c 100644 --- a/gc/base/SparseVirtualMemory.cpp +++ b/gc/base/SparseVirtualMemory.cpp @@ -45,14 +45,15 @@ **************************************** */ -MM_SparseVirtualMemory* +MM_SparseVirtualMemory * MM_SparseVirtualMemory::newInstance(MM_EnvironmentBase* env, uint32_t memoryCategory, MM_Heap *in_heap) { + MM_GCExtensionsBase *extensions = env->getExtensions(); MM_SparseVirtualMemory* vmem = NULL; vmem = (MM_SparseVirtualMemory*)env->getForge()->allocate(sizeof(MM_SparseVirtualMemory), OMR::GC::AllocationCategory::FIXED, OMR_GET_CALLSITE()); if (vmem) { - new (vmem) MM_SparseVirtualMemory(env, in_heap->getPageSize(), in_heap); + new (vmem) MM_SparseVirtualMemory(env, extensions->sparseHeapPageSize, extensions->sparseHeapPageFlags, in_heap); if (!vmem->initialize(env, memoryCategory)) { vmem->kill(env); vmem = NULL; diff --git a/gc/base/SparseVirtualMemory.hpp b/gc/base/SparseVirtualMemory.hpp index 1f9bf80653a..99339720e02 100644 --- a/gc/base/SparseVirtualMemory.hpp +++ b/gc/base/SparseVirtualMemory.hpp @@ -84,8 +84,8 @@ class MM_SparseVirtualMemory : public MM_VirtualMemory { bool initialize(MM_EnvironmentBase* env, uint32_t memoryCategory); void tearDown(MM_EnvironmentBase *env); - MM_SparseVirtualMemory(MM_EnvironmentBase* env, uintptr_t pageSize, MM_Heap *in_heap) - : MM_VirtualMemory(env, env->getExtensions()->heapAlignment, pageSize, env->getExtensions()->requestedPageFlags, 0, OMRPORT_VMEM_MEMORY_MODE_READ | OMRPORT_VMEM_MEMORY_MODE_WRITE) + MM_SparseVirtualMemory(MM_EnvironmentBase* env, uintptr_t pageSize, uintptr_t pageFlags, MM_Heap *in_heap) + : MM_VirtualMemory(env, env->getExtensions()->heapAlignment, pageSize, pageFlags, 0, OMRPORT_VMEM_MEMORY_MODE_READ | OMRPORT_VMEM_MEMORY_MODE_WRITE) , _heap(in_heap) , _sparseDataPool(NULL) , _largeObjectVirtualMemoryMutex(NULL)