Skip to content

Commit c9fd57b

Browse files
Aleksandar MicicAleksandar Micic
Aleksandar Micic
authored and
Aleksandar Micic
committed
Allocate RS Control Blocks for Balanced as virtual memory
Currently, all Control Blocks (kind of a header structure) for Remembered Set Buffers, for all possible regions, are allocated upfront with one big malloc. This is suboptimal from footprint perspective. Also, in extreme cases with very large heaps the allocation may not even succeed. We will now allocate that space as Virtual Memory which will be lazily committed as needed (as regions are first time used and their RSCL is first time initialized). RS Buffers themselves are already allocated incrementally/gradually, as regions are first time used, although still malloced. In future, we may want to allocate them as virtual memory too, but currently that is less important (relative to Control Blocks) due to their incremental allocation. Signed-off-by: Aleksandar Micic <Aleksandar_Micic@ca.ibm.com>
1 parent af5aa2c commit c9fd57b

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

runtime/gc_vlhgc/InterRegionRememberedSet.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
MM_InterRegionRememberedSet::MM_InterRegionRememberedSet(MM_HeapRegionManager *heapRegionManager)
4949
: _heapRegionManager(heapRegionManager)
50+
, _rsclBufferControlBlockPoolMemoryHandle()
5051
, _rsclBufferControlBlockPool(NULL)
5152
, _rsclBufferControlBlockHead(NULL)
5253
, _freeBufferCount(0)
@@ -239,7 +240,7 @@ MM_InterRegionRememberedSet::allocateRegionBuffers(MM_EnvironmentVLHGC* env, MM_
239240
}
240241

241242
bool
242-
MM_InterRegionRememberedSet::initialize(MM_EnvironmentVLHGC* env)
243+
MM_InterRegionRememberedSet::initialize(MM_EnvironmentVLHGC *env)
243244
{
244245
MM_GCExtensions *ext = MM_GCExtensions::getExtensions(env);
245246

@@ -255,8 +256,17 @@ MM_InterRegionRememberedSet::initialize(MM_EnvironmentVLHGC* env)
255256
UDATA bufferSize = MM_RememberedSetCardBucket::MAX_BUFFER_SIZE * cardSize;
256257
Assert_MM_true(((UDATA)1 << MM_Bits::leadingZeroes(bufferSize)) == bufferSize);
257258

258-
/* All Buffer Control Block are pre-allocated on startup. Buffers themselves are allocated as regions are commited */
259-
_rsclBufferControlBlockPool = (MM_CardBufferControlBlock *)ext->getForge()->allocate(rsclBufferControlBlockPoolSize, MM_AllocationCategory::REMEMBERED_SET, J9_GET_CALLSITE());
259+
/* All Buffer Control Block are pre-allocated on startup, based on maximum heap size. Buffers themselves are allocated as regions are used first time.
260+
* Since Control Blocks consume considerable amount of memory, they are allocated as virtual memory,
261+
* so they can be lazily committed as regions are effectively used (when their RSCL is first time initialized). */
262+
MM_MemoryManager *memoryManager = ext->memoryManager;
263+
if (memoryManager->createVirtualMemoryForMetadata(env, &_rsclBufferControlBlockPoolMemoryHandle, ext->heapAlignment, rsclBufferControlBlockPoolSize)) {
264+
_rsclBufferControlBlockPool = (MM_CardBufferControlBlock *)memoryManager->getHeapBase(&_rsclBufferControlBlockPoolMemoryHandle);
265+
if (!memoryManager->commitMemory(&_rsclBufferControlBlockPoolMemoryHandle, _rsclBufferControlBlockPool, rsclBufferControlBlockPoolSize)) {
266+
_rsclBufferControlBlockPool = NULL;
267+
}
268+
}
269+
260270
if (NULL == _rsclBufferControlBlockPool) {
261271
return false;
262272
}
@@ -468,15 +478,15 @@ MM_InterRegionRememberedSet::releaseCardBufferControlBlockLocalPools(MM_Environm
468478

469479

470480
void
471-
MM_InterRegionRememberedSet::tearDown(MM_EnvironmentBase* env)
481+
MM_InterRegionRememberedSet::tearDown(MM_EnvironmentBase *env)
472482
{
473483
MM_GCExtensions *ext = MM_GCExtensions::getExtensions(env);
474484

475485
if (NULL != _rsclBufferControlBlockPool) {
476-
ext->getForge()->free(_rsclBufferControlBlockPool);
486+
ext->memoryManager->destroyVirtualMemory(env, &_rsclBufferControlBlockPoolMemoryHandle);
487+
_rsclBufferControlBlockPool = NULL;
477488
}
478489

479-
/* TODO: _lock initialize might have failed */
480490
_lock.tearDown();
481491
}
482492

runtime/gc_vlhgc/InterRegionRememberedSet.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class MM_InterRegionRememberedSet : public MM_BaseVirtual
5757
public:
5858
MM_HeapRegionManager *_heapRegionManager; /**< cached pointer to heap region manager */
5959

60+
MM_MemoryHandle _rsclBufferControlBlockPoolMemoryHandle; /**< memory handle for Control Blocks (but not Buffers) backing store */
61+
6062
MM_CardBufferControlBlock *_rsclBufferControlBlockPool; /**< starting address of the global pool of control blocks (kept around to be able to release memory at the end) */
6163
MM_CardBufferControlBlock * volatile _rsclBufferControlBlockHead; /**< current head of BufferControlBlock global pool list */
6264
volatile UDATA _freeBufferCount; /**< current count of Buffers in the global free pool */
@@ -69,7 +71,7 @@ class MM_InterRegionRememberedSet : public MM_BaseVirtual
6971

7072
UDATA _regionSize; /**< Cached region size */
7173

72-
bool _shouldFlushBuffersForDecommitedRegions; /**< set to true at the end of a GC, if contraction occured. this is a signal for the next GC to perform flush buffers from regions contracted */
74+
bool _shouldFlushBuffersForDecommitedRegions; /**< set to true at the end of a GC, if contraction occurred. this is a signal for the next GC to perform flush buffers from regions contracted */
7375

7476
volatile UDATA _overflowedRegionCount; /**< count of regions overflowed as full */
7577
UDATA _stableRegionCount; /**< count of regions overflowed as stable */

0 commit comments

Comments
 (0)