Skip to content

Commit dd8b5ac

Browse files
committed
Handling multiple reserved region lists for numa off-heap case
In PR #22116 and #22546, _arrayReservedRegionList and _sharedArrayReservedRegionsBytesUsed has been introduced to share fraction of reserved regions. _arrayReservedRegionList is set in commonAllocationContext(single global list), For numa case, the reserved regions for large array could be allocated from different allocation context(allocation context per numa node and in case there is no free region for the numa note, it could borrow from neighbor numa node). during recycling, there are no extra information indicate which reserved regions are for recycling off-heap array, so potentially it might cause imbalance free memory among numa notes, then affect runtime performance in some cases. Undate to manage reserved region list per allocation context(numa note) to avoid imbalance free memory caused by reserved regions. 1, for reducing complexity, shared fraction reserved regions still be managed in _arrayReservedRegionList of commom context. set _sharedReserved in AllocateDescriptor for shared fraction reserved region allocation. 2, new _allocationContextArray in SparseVirtualMemory(omr PR eclipse-omr/omr#7956) to store/retrieve allocation context for the reserved regions of large array. 3, handle allocation failure during getSparseAddressAndDecommitLeaves(). Signed-off-by: lhu <[email protected]>
1 parent 31abe0e commit dd8b5ac

File tree

6 files changed

+85
-38
lines changed

6 files changed

+85
-38
lines changed

runtime/gc_base/IndexableObjectAllocationModel.cpp

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "MemorySpace.hpp"
2828
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
2929
#include "AllocationContextBalanced.hpp"
30+
#include "HeapRegionDataForAllocate.hpp"
3031
#include "EnvironmentVLHGC.hpp"
3132
#endif /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */
3233
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) || defined(J9VM_GC_ENABLE_DOUBLE_MAP)
@@ -345,12 +346,19 @@ MM_IndexableObjectAllocationModel::getSparseAddressAndDecommitLeaves(MM_Environm
345346
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(envBase);
346347
GC_ArrayObjectModel *indexableObjectModel = &extensions->indexableObjectModel;
347348
const uintptr_t regionSize = extensions->heapRegionManager->getRegionSize();
348-
349349
uintptr_t byteAmount = 0;
350350

351351
/* Determine how many bytes to allocate outside of the spine (in arraylet leaves). */
352352
Assert_MM_true(_allocateDescription.getBytesRequested() >= _allocateDescription.getContiguousBytes());
353353
uintptr_t bytesRemaining = _allocateDescription.getBytesRequested() - _allocateDescription.getContiguousBytes();
354+
#define REGION_RESERVE_THRESHOLD 64
355+
void *allocationContexts[REGION_RESERVE_THRESHOLD];
356+
void **reservedRegionAllocationContexts = allocationContexts;
357+
uintptr_t reservedRegionCount = bytesRemaining / regionSize;
358+
359+
if (reservedRegionCount > REGION_RESERVE_THRESHOLD) {
360+
reservedRegionAllocationContexts = (void **)envBase->getForge()->allocate(reservedRegionCount * sizeof(uintptr_t), MM_AllocationCategory::GC_HEAP, J9_GET_CALLSITE());
361+
}
354362

355363
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(envBase);
356364
MM_AllocationContextBalanced *commonContext = (MM_AllocationContextBalanced *)env->getCommonAllocationContext();
@@ -359,26 +367,44 @@ MM_IndexableObjectAllocationModel::getSparseAddressAndDecommitLeaves(MM_Environm
359367
uintptr_t arrayReservedRegionCount = 0;
360368
uintptr_t fraction = 0;
361369
while (0 < bytesRemaining) {
362-
/* Allocate the next arraylet leaf - leaves are allocated solely for the purpose of
370+
/* Allocate the next reserved region - reserved regions are allocated solely for the purpose of
363371
decommitting the memory later on in this function. */
364372
void *reservedAddressLow = NULL;
365373
bool shouldAllocateReservedRegion = true;
374+
366375
if (regionSize > bytesRemaining) {
367376
fraction = bytesRemaining;
368377
/* For code simplicity and lower fragmentation, we always use Common Context. */
369378
shouldAllocateReservedRegion = commonContext->allocateFromSharedArrayReservedRegion(envBase, fraction);
370379
}
371380
if (shouldAllocateReservedRegion) {
381+
_allocateDescription.setSharedReserved(0 != fraction);
382+
372383
reservedAddressLow = envBase->_objectAllocationInterface->allocateArrayletLeaf(
373384
envBase, &_allocateDescription, _allocateDescription.getMemorySpace(), true);
374385

375386
/* If reservedRegion allocation failed set the result to NULL and return. */
376387
if (NULL == reservedAddressLow) {
377388
Trc_MM_allocateAndConnectNonContiguousArraylet_leafFailure(envBase->getLanguageVMThread());
378389
_allocateDescription.setSpine(NULL);
390+
if (0 != fraction) {
391+
commonContext->recycleToSharedArrayReservedRegion(envBase, fraction);
392+
fraction = 0;
393+
}
379394
spine = NULL;
380395
break;
381396
}
397+
398+
if (0 == fraction) {
399+
MM_HeapRegionDescriptorVLHGC *reservedRegion = (MM_HeapRegionDescriptorVLHGC *)extensions->heapRegionManager->regionDescriptorForAddress(reservedAddressLow);
400+
MM_HeapRegionDataForAllocate *allocateData = &reservedRegion->_allocateData;
401+
if (NULL != allocateData->_originalOwningContext) {
402+
reservedRegionAllocationContexts[arrayReservedRegionCount] = allocateData->_originalOwningContext;
403+
} else {
404+
reservedRegionAllocationContexts[arrayReservedRegionCount] = allocateData->_owningContext;
405+
}
406+
}
407+
382408
/* Disable region for reads and writes, since accessing virtualLargeObjectHeapAddress through DataAddrForContiguous */
383409
void *reservedAddressHigh = (void *)((uintptr_t)reservedAddressLow + regionSize);
384410
bool ret = extensions->heap->decommitMemory(reservedAddressLow, regionSize, reservedAddressLow, reservedAddressHigh);
@@ -391,17 +417,22 @@ MM_IndexableObjectAllocationModel::getSparseAddressAndDecommitLeaves(MM_Environm
391417
}
392418

393419
bytesRemaining -= OMR_MIN(bytesRemaining, regionSize);
394-
arrayReservedRegionCount += 1;
420+
if (0 == fraction) {
421+
arrayReservedRegionCount += 1;
422+
}
395423
}
396424

397-
398425
if (NULL != spine) {
399426
Assert_MM_true(_layout == GC_ArrayletObjectModel::InlineContiguous);
400427
Assert_MM_true(indexableObjectModel->isVirtualLargeObjectHeapEnabled());
401428

402429
byteAmount = _dataSize;
403430
void *virtualLargeObjectHeapAddress = extensions->largeObjectVirtualMemory->allocateSparseFreeEntryAndMapToHeapObject(spine, byteAmount);
404431

432+
for (uintptr_t idx = 0; idx < arrayReservedRegionCount; idx++) {
433+
extensions->largeObjectVirtualMemory->setAllocationContextForAddress(virtualLargeObjectHeapAddress, reservedRegionAllocationContexts[idx], idx);
434+
}
435+
405436
if (NULL != virtualLargeObjectHeapAddress) {
406437
indexableObjectModel->setDataAddrForContiguous((J9IndexableObject *)spine, virtualLargeObjectHeapAddress);
407438
} else {
@@ -414,13 +445,21 @@ MM_IndexableObjectAllocationModel::getSparseAddressAndDecommitLeaves(MM_Environm
414445
/* fail to reserve regions or allocateSparseFreeEntry, clean up reserved regions */
415446
if (0 != fraction) {
416447
/* rollback fraction */
417-
commonContext->recycleToSharedArrayReservedRegion(envBase, fraction);
448+
if (commonContext->recycleToSharedArrayReservedRegion(envBase, fraction)) {
449+
commonContext->recycleReservedRegionsForVirtualLargeObjectHeap(env, 1, true);
450+
}
418451
}
419452
if (0 < arrayReservedRegionCount) {
420-
((MM_HeapRegionManagerVLHGC *)extensions->heapRegionManager)->recycleReservedRegionsForVirtualLargeObjectHeap(envBase, arrayReservedRegionCount);
453+
for (uintptr_t idx = 0; idx < arrayReservedRegionCount; idx++) {
454+
((MM_AllocationContextBalanced *)reservedRegionAllocationContexts[idx])->recycleReservedRegionsForVirtualLargeObjectHeap(env, 1, true);
455+
}
421456
}
422457
}
423458

459+
if (reservedRegionCount > REGION_RESERVE_THRESHOLD) {
460+
env->getForge()->free((void *)reservedRegionAllocationContexts);
461+
}
462+
424463
Trc_MM_getSparseAddressAndDecommitLeaves_Exit(envBase->getLanguageVMThread(), spine, (void *)bytesRemaining);
425464

426465
return spine;

runtime/gc_vlhgc/AllocationContextBalanced.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -391,18 +391,21 @@ MM_AllocationContextBalanced::lockedAllocateArrayletLeaf(MM_EnvironmentBase *env
391391
* In future, allocations should remember (somewhere in Off-heap meta structures) how many regions came from each AC
392392
* \and release exact same number back to each AC.
393393
*/
394-
MM_AllocationContextTarok *commonContext = (MM_AllocationContextTarok *)env->getCommonAllocationContext();
395-
if (this != commonContext) {
394+
MM_AllocationContextTarok *context = this;
395+
if (allocateDescription->getSharedReserved()) {
396+
context = (MM_AllocationContextTarok *)env->getCommonAllocationContext();
397+
}
398+
if (this != context) {
396399
/* The common allocation context is always an instance of AllocationContextBalanced */
397-
((MM_AllocationContextBalanced *)commonContext)->lockCommon();
400+
((MM_AllocationContextBalanced *)context)->lockCommon();
398401
}
399402

400-
leafAllocateData->pushRegionToArrayReservedRegionList(env, ((MM_AllocationContextBalanced *)commonContext)->getArrayReservedRegionListAddress());
401-
((MM_AllocationContextBalanced *)commonContext)->incrementArrayReservedRegionCount();
403+
leafAllocateData->pushRegionToArrayReservedRegionList(env, ((MM_AllocationContextBalanced *)context)->getArrayReservedRegionListAddress());
404+
((MM_AllocationContextBalanced *)context)->incrementArrayReservedRegionCount();
402405

403-
if (this != commonContext) {
406+
if (this != context) {
404407
/* The common allocation context is always an instance of AllocationContextBalanced */
405-
((MM_AllocationContextBalanced *)commonContext)->unlockCommon();
408+
((MM_AllocationContextBalanced *)context)->unlockCommon();
406409
}
407410
}
408411
#endif /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */

runtime/gc_vlhgc/CopyForwardScheme.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4174,17 +4174,29 @@ class MM_CopyForwardSchemeRootClearer : public MM_RootScanner
41744174
uintptr_t reservedRegionCount = dataSize / regionSize;
41754175
uintptr_t fraction = dataSize % regionSize;
41764176

4177-
MM_AllocationContextBalanced *commonContext = (MM_AllocationContextBalanced *)env->getCommonAllocationContext();
4178-
if ((0 != fraction) && commonContext->recycleToSharedArrayReservedRegion(env, fraction)) {
4179-
reservedRegionCount += 1;
4180-
}
4177+
PORT_ACCESS_FROM_ENVIRONMENT(env);
4178+
j9tty_printf(PORTLIB, "MM_CopyForwardSchemeRootClearer::doObjectInVirtualLargeObjectHeap reservedRegionCount=%zu, fraction=%zu, dataSize=%zu, regionSize=%zu\n",
4179+
reservedRegionCount, fraction, dataSize, regionSize);
41814180

41824181
Assert_MM_mustBeClass(_extensions->objectModel.getPreservedClass(&forwardedHeader));
41834182
env->_copyForwardStats._offHeapRegionsCleared += 1;
41844183
void *dataAddr = _extensions->indexableObjectModel.getDataAddrForContiguous((J9IndexableObject *)objectPtr);
4185-
_extensions->largeObjectVirtualMemory->freeSparseRegionAndUnmapFromHeapObject(_env, dataAddr, objectPtr, dataSize, sparseDataEntryIterator);
4184+
4185+
MM_SparseVirtualMemory *largeObjectVirtualMemory = _extensions->largeObjectVirtualMemory;
41864186
/* recycleLeafRegions for off-heap case */
4187-
commonContext->recycleReservedRegionsForVirtualLargeObjectHeap(env, reservedRegionCount);
4187+
MM_AllocationContextBalanced *context = NULL;
4188+
for (uintptr_t index = 0; index < reservedRegionCount; index++) {
4189+
context = (MM_AllocationContextBalanced *) largeObjectVirtualMemory->getAllocationContextForAddress(dataAddr, index);
4190+
context->recycleReservedRegionsForVirtualLargeObjectHeap(env, 1);
4191+
}
4192+
4193+
/* commonContext for fraction region */
4194+
context = (MM_AllocationContextBalanced *)env->getCommonAllocationContext();
4195+
if ((0 != fraction) && context->recycleToSharedArrayReservedRegion(env, fraction)) {
4196+
context->recycleReservedRegionsForVirtualLargeObjectHeap(env, 1);
4197+
}
4198+
4199+
_extensions->largeObjectVirtualMemory->freeSparseRegionAndUnmapFromHeapObject(_env, dataAddr, objectPtr, dataSize, sparseDataEntryIterator);
41884200
} else {
41894201
void *dataAddr = _extensions->indexableObjectModel.getDataAddrForContiguous((J9IndexableObject *)fwdOjectPtr);
41904202
if (NULL != dataAddr) {

runtime/gc_vlhgc/GlobalMarkingScheme.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,14 +1431,22 @@ class MM_GlobalMarkingSchemeRootClearer : public MM_RootScanner
14311431

14321432
uintptr_t reservedRegionCount = dataSize / regionSize;
14331433
uintptr_t fraction = dataSize % regionSize;
1434-
MM_AllocationContextBalanced *commonContext = (MM_AllocationContextBalanced *)env->getCommonAllocationContext();
14351434

1436-
if ((0 != fraction) && commonContext->recycleToSharedArrayReservedRegion(env, fraction)) {
1437-
reservedRegionCount += 1;
1435+
MM_SparseVirtualMemory *largeObjectVirtualMemory = _extensions->largeObjectVirtualMemory;
1436+
/* recycleLeafRegions for off-heap case */
1437+
MM_AllocationContextBalanced *context = NULL;
1438+
for (uintptr_t index = 0; index < reservedRegionCount; index++) {
1439+
context = (MM_AllocationContextBalanced *) largeObjectVirtualMemory->getAllocationContextForAddress(dataAddr, index);
1440+
context->recycleReservedRegionsForVirtualLargeObjectHeap(env, 1);
1441+
}
1442+
1443+
/* commonContext for fraction region */
1444+
context = (MM_AllocationContextBalanced *)env->getCommonAllocationContext();
1445+
if ((0 != fraction) && context->recycleToSharedArrayReservedRegion(env, fraction)) {
1446+
context->recycleReservedRegionsForVirtualLargeObjectHeap(env, 1);
14381447
}
14391448

14401449
_extensions->largeObjectVirtualMemory->freeSparseRegionAndUnmapFromHeapObject(_env, dataAddr, objectPtr, dataSize, sparseDataEntryIterator);
1441-
commonContext->recycleReservedRegionsForVirtualLargeObjectHeap(env, reservedRegionCount);
14421450
}
14431451
}
14441452
}

runtime/gc_vlhgc/HeapRegionManagerVLHGC.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,3 @@ MM_HeapRegionManagerVLHGC::getHeapMemorySnapshot(MM_GCExtensionsBase *extensions
222222

223223
return snapshot;
224224
}
225-
226-
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
227-
void
228-
MM_HeapRegionManagerVLHGC::recycleReservedRegionsForVirtualLargeObjectHeap(MM_EnvironmentBase *envBase, uintptr_t reservedRegionCount)
229-
{
230-
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(envBase);
231-
MM_AllocationContextBalanced *commonContext = (MM_AllocationContextBalanced *)env->getCommonAllocationContext();
232-
233-
commonContext->recycleReservedRegionsForVirtualLargeObjectHeap(env, reservedRegionCount, true);
234-
}
235-
#endif /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */

runtime/gc_vlhgc/HeapRegionManagerVLHGC.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ class MM_HeapRegionManagerVLHGC : public MM_HeapRegionManagerTarok
4242

4343
virtual MM_HeapMemorySnapshot *getHeapMemorySnapshot(MM_GCExtensionsBase *extensions, MM_HeapMemorySnapshot *snapshot, bool gcEnd);
4444

45-
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
46-
void recycleReservedRegionsForVirtualLargeObjectHeap(MM_EnvironmentBase *envBase, uintptr_t reservedRegionCount);
47-
#endif /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */
48-
4945
static MM_HeapRegionManagerVLHGC *newInstance(MM_EnvironmentBase *env, uintptr_t regionSize, uintptr_t tableDescriptorSize, MM_RegionDescriptorInitializer regionDescriptorInitializer, MM_RegionDescriptorDestructor regionDescriptorDestructor);
5046
MM_HeapRegionManagerVLHGC(MM_EnvironmentBase *env, uintptr_t regionSize, uintptr_t tableDescriptorSize, MM_RegionDescriptorInitializer regionDescriptorInitializer, MM_RegionDescriptorDestructor regionDescriptorDestructor);
5147

0 commit comments

Comments
 (0)