Skip to content

Commit

Permalink
Merge pull request eclipse-openj9#17614 from RSalman/reinit-region
Browse files Browse the repository at this point in the history
GC CRIU: Reinit HeapRegionDescriptorExtensions (Region Obj Lists)
  • Loading branch information
amicic committed Jun 21, 2023
2 parents 4509ed4 + 6a1b378 commit ba637b2
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 45 deletions.
17 changes: 13 additions & 4 deletions runtime/gc_base/ContinuationObjectList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,22 @@ MM_ContinuationObjectList::MM_ContinuationObjectList()
}

MM_ContinuationObjectList *
MM_ContinuationObjectList::newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElements)
MM_ContinuationObjectList::newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElementsTotal, MM_ContinuationObjectList *listsToCopy, uintptr_t arrayElementsToCopy)
{
MM_ContinuationObjectList *continuationObjectLists;
MM_ContinuationObjectList *continuationObjectLists = NULL;

continuationObjectLists = (MM_ContinuationObjectList *)env->getForge()->allocate(sizeof(MM_ContinuationObjectList) * arrayElements, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
continuationObjectLists = (MM_ContinuationObjectList *)env->getForge()->allocate(sizeof(MM_ContinuationObjectList) * arrayElementsTotal, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
if (NULL != continuationObjectLists) {
for (uintptr_t index = 0; index < arrayElements; index++) {
Assert_MM_true(arrayElementsTotal >= arrayElementsToCopy);
/* Check whether a new array instance in being created from an existing array. If so, copy over the elements first. */
if (arrayElementsToCopy > 0) {
for (uintptr_t index = 0; index < arrayElementsToCopy; index++) {
continuationObjectLists[index] = listsToCopy[index];
continuationObjectLists[index].initialize(env);
}
}

for (uintptr_t index = arrayElementsToCopy; index < arrayElementsTotal; index++) {
new(&continuationObjectLists[index]) MM_ContinuationObjectList();
continuationObjectLists[index].initialize(env);
}
Expand Down
6 changes: 4 additions & 2 deletions runtime/gc_base/ContinuationObjectList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ class MM_ContinuationObjectList : public MM_BaseNonVirtual
* Allocate and initialize an array of MM_ContinuationObjectList instances, resembling the functionality of operator new[].
*
* @param env the current thread
* @param arrayElements the number of lists to create
* @param arrayElementsTotal the number of lists to create
* @param listsToCopy existing MM_ContinuationObjectList array to use to construct a new array of lists
* @param arrayElementsToCopy the size of the list array to be copied
*
* @return a pointer to the first list in the array, or NULL if we failed to allocate/init the array
*/
static MM_ContinuationObjectList *newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElements);
static MM_ContinuationObjectList *newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElementsTotal, MM_ContinuationObjectList *listsToCopy, uintptr_t arrayElementsToCopy);
bool initialize(MM_EnvironmentBase *env);

/**
Expand Down
17 changes: 13 additions & 4 deletions runtime/gc_base/OwnableSynchronizerObjectList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,22 @@ MM_OwnableSynchronizerObjectList::MM_OwnableSynchronizerObjectList()
}

MM_OwnableSynchronizerObjectList *
MM_OwnableSynchronizerObjectList::newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElements)
MM_OwnableSynchronizerObjectList::newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElementsTotal, MM_OwnableSynchronizerObjectList *listsToCopy, uintptr_t arrayElementsToCopy)
{
MM_OwnableSynchronizerObjectList *ownableSynchronizerObjectLists;
MM_OwnableSynchronizerObjectList *ownableSynchronizerObjectLists = NULL;

ownableSynchronizerObjectLists = (MM_OwnableSynchronizerObjectList *)env->getForge()->allocate(sizeof(MM_OwnableSynchronizerObjectList) * arrayElements, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
ownableSynchronizerObjectLists = (MM_OwnableSynchronizerObjectList *)env->getForge()->allocate(sizeof(MM_OwnableSynchronizerObjectList) * arrayElementsTotal, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
if (NULL != ownableSynchronizerObjectLists) {
for (uintptr_t index = 0; index < arrayElements; index++) {
Assert_MM_true(arrayElementsTotal >= arrayElementsToCopy);
/* Check whether a new array instance in being created from an existing array. If so, copy over the elements first. */
if (arrayElementsToCopy > 0) {
for (uintptr_t index = 0; index < arrayElementsToCopy; index++) {
ownableSynchronizerObjectLists[index] = listsToCopy[index];
ownableSynchronizerObjectLists[index].initialize(env);
}
}

for (uintptr_t index = arrayElementsToCopy; index < arrayElementsTotal; index++) {
new(&ownableSynchronizerObjectLists[index]) MM_OwnableSynchronizerObjectList();
ownableSynchronizerObjectLists[index].initialize(env);
}
Expand Down
6 changes: 4 additions & 2 deletions runtime/gc_base/OwnableSynchronizerObjectList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ class MM_OwnableSynchronizerObjectList : public MM_BaseNonVirtual
* Allocate and initialize an array of MM_OwnableSynchronizerObjectList instances, resembling the functionality of operator new[].
*
* @param env the current thread
* @param arrayElements the number of lists to create
* @param arrayElementsTotal the number of lists to create
* @param listsToCopy existing MM_OwnableSynchronizerObjectList array to use to construct a new array of lists
* @param arrayElementsToCopy the size of the list array to be copied
*
* @return a pointer to the first list in the array, or NULL if we failed to allocate/init the array
*/
static MM_OwnableSynchronizerObjectList *newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElements);
static MM_OwnableSynchronizerObjectList *newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElementsTotal, MM_OwnableSynchronizerObjectList *listsToCopy, uintptr_t arrayElementsToCopy);
bool initialize(MM_EnvironmentBase *env);

/**
Expand Down
17 changes: 13 additions & 4 deletions runtime/gc_base/ReferenceObjectList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,22 @@ MM_ReferenceObjectList::MM_ReferenceObjectList()
}

MM_ReferenceObjectList *
MM_ReferenceObjectList::newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElements)
MM_ReferenceObjectList::newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElementsTotal, MM_ReferenceObjectList *listsToCopy, uintptr_t arrayElementsToCopy)
{
MM_ReferenceObjectList *referenceObjectLists;
MM_ReferenceObjectList *referenceObjectLists = NULL;

referenceObjectLists = (MM_ReferenceObjectList *)env->getForge()->allocate(sizeof(MM_ReferenceObjectList) * arrayElements, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
referenceObjectLists = (MM_ReferenceObjectList *)env->getForge()->allocate(sizeof(MM_ReferenceObjectList) * arrayElementsTotal, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
if (NULL != referenceObjectLists) {
for (uintptr_t index = 0; index < arrayElements; index++) {
Assert_MM_true(arrayElementsTotal >= arrayElementsToCopy);
/* Check whether a new array instance in being created from an existing array. If so, copy over the elements first. */
if (arrayElementsToCopy > 0) {
for (uintptr_t index = 0; index < arrayElementsToCopy; index++) {
referenceObjectLists[index] = listsToCopy[index];
referenceObjectLists[index].initialize(env);
}
}

for (uintptr_t index = arrayElementsToCopy; index < arrayElementsTotal; index++) {
new(&referenceObjectLists[index]) MM_ReferenceObjectList();
referenceObjectLists[index].initialize(env);
}
Expand Down
6 changes: 4 additions & 2 deletions runtime/gc_base/ReferenceObjectList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ class MM_ReferenceObjectList : public MM_BaseNonVirtual
* Allocate and initialize an array of MM_ReferenceObjectList instances, resembling the functionality of operator new[].
*
* @param env the current thread
* @param arrayElements the number of lists to create
* @param arrayElementsTotal the number of lists to create
* @param listsToCopy existing MM_ReferenceObjectList array to use to construct a new array of lists
* @param arrayElementsToCopy the size of the list array to be copied
*
* @return a pointer to the first list in the array, or NULL if we failed to allocate/init the array
*/
static MM_ReferenceObjectList *newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElements);
static MM_ReferenceObjectList *newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElementsTotal, MM_ReferenceObjectList *listsToCopy, uintptr_t arrayElementsToCopy);
bool initialize(MM_EnvironmentBase *env) { return true; }

/**
Expand Down
17 changes: 13 additions & 4 deletions runtime/gc_base/UnfinalizedObjectList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,22 @@ MM_UnfinalizedObjectList::MM_UnfinalizedObjectList()
}

MM_UnfinalizedObjectList *
MM_UnfinalizedObjectList::newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElements)
MM_UnfinalizedObjectList::newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElementsTotal, MM_UnfinalizedObjectList *listsToCopy, uintptr_t arrayElementsToCopy)
{
MM_UnfinalizedObjectList *unfinalizedObjectLists;
MM_UnfinalizedObjectList *unfinalizedObjectLists = NULL;

unfinalizedObjectLists = (MM_UnfinalizedObjectList *)env->getForge()->allocate(sizeof(MM_UnfinalizedObjectList) * arrayElements, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
unfinalizedObjectLists = (MM_UnfinalizedObjectList *)env->getForge()->allocate(sizeof(MM_UnfinalizedObjectList) * arrayElementsTotal, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
if (NULL != unfinalizedObjectLists) {
for (uintptr_t index = 0; index < arrayElements; index++) {
Assert_MM_true(arrayElementsTotal >= arrayElementsToCopy);
/* Check whether a new array instance in being created from an existing array. If so, copy over the elements first. */
if (arrayElementsToCopy > 0) {
for (uintptr_t index = 0; index < arrayElementsToCopy; index++) {
unfinalizedObjectLists[index] = listsToCopy[index];
unfinalizedObjectLists[index].initialize(env);
}
}

for (uintptr_t index = arrayElementsToCopy; index < arrayElementsTotal; index++) {
new(&unfinalizedObjectLists[index]) MM_UnfinalizedObjectList();
unfinalizedObjectLists[index].initialize(env);
}
Expand Down
6 changes: 4 additions & 2 deletions runtime/gc_base/UnfinalizedObjectList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ class MM_UnfinalizedObjectList : public MM_BaseNonVirtual
* Allocate and initialize an array of MM_UnfinalizedObjectList instances, resembling the functionality of operator new[].
*
* @param env the current thread
* @param arrayElements the number of lists to create
* @param arrayElementsTotal the number of lists to create
* @param listsToCopy existing MM_UnfinalizedObjectList array to use to construct a new array of lists
* @param arrayElementsToCopy the size of the list array to be copied
*
* @return a pointer to the first list in the array, or NULL if we failed to allocate/init the array
*/
static MM_UnfinalizedObjectList *newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElements);
static MM_UnfinalizedObjectList *newInstanceArray(MM_EnvironmentBase *env, uintptr_t arrayElementsTotal, MM_UnfinalizedObjectList *listsToCopy, uintptr_t arrayElementsToCopy);
bool initialize(MM_EnvironmentBase *env);

/**
Expand Down
35 changes: 35 additions & 0 deletions runtime/gc_glue_java/ConfigurationDelegate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "HeapRegionDescriptor.hpp"
#include "HeapRegionDescriptorStandardExtension.hpp"
#include "HeapRegionManager.hpp"
#include "HeapRegionIterator.hpp"
#include "ObjectAccessBarrier.hpp"
#include "ObjectAllocationInterface.hpp"
#include "StringTable.hpp"
Expand Down Expand Up @@ -154,6 +155,40 @@ class MM_ConfigurationDelegate
return regionExtension;
}

#if defined(J9VM_OPT_CRIU_SUPPORT)
void
reinitializeGCParameters(MM_EnvironmentBase* env)
{
/* reinitialize the size of Local Object Buffers */
uintptr_t objectListFragmentCount = (4 * _extensions->gcThreadCount) + 4;
_extensions->objectListFragmentCount = OMR_MAX(_extensions->objectListFragmentCount, objectListFragmentCount);
}

bool
reinitializeForRestore(MM_EnvironmentBase* env)
{
Assert_MM_true(_extensions->isStandardGC());

reinitializeGCParameters(env);

MM_HeapRegionDescriptor *region = NULL;
GC_HeapRegionIterator regionIterator(_extensions->heap->getHeapRegionManager());

_extensions->unfinalizedObjectLists = NULL;
_extensions->setOwnableSynchronizerObjectLists(NULL);
_extensions->setContinuationObjectLists(NULL);

while (NULL != (region = regionIterator.nextRegion())) {
MM_HeapRegionDescriptorStandardExtension *regionExtension = getHeapRegionDescriptorStandardExtension(env, region);
if (!regionExtension->reinitializeForRestore(env)) {
return false;
}
}

return true;
}
#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */

bool
initializeHeapRegionDescriptorExtension(MM_EnvironmentBase *env, MM_HeapRegionDescriptor *region)
{
Expand Down
84 changes: 63 additions & 21 deletions runtime/gc_glue_java/HeapRegionDescriptorStandardExtension.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,60 @@ class MM_HeapRegionDescriptorStandardExtension : public MM_BaseNonVirtual
bool
initialize(MM_EnvironmentBase *env)
{
if (NULL == (_unfinalizedObjectLists = MM_UnfinalizedObjectList::newInstanceArray(env, _maxListIndex))) {
if ((NULL == (_unfinalizedObjectLists = MM_UnfinalizedObjectList::newInstanceArray(env, _maxListIndex, NULL, 0)))
|| (NULL == (_ownableSynchronizerObjectLists = MM_OwnableSynchronizerObjectList::newInstanceArray(env, _maxListIndex, NULL, 0)))
|| (NULL == (_continuationObjectLists = MM_ContinuationObjectList::newInstanceArray(env, _maxListIndex, NULL, 0)))
|| (NULL == (_referenceObjectLists = MM_ReferenceObjectList::newInstanceArray(env, _maxListIndex, NULL, 0)))
) {
tearDown(env);
return false;
}

if (NULL == (_ownableSynchronizerObjectLists = MM_OwnableSynchronizerObjectList::newInstanceArray(env, _maxListIndex))) {
return false;
}
return true;
}

if (NULL == (_continuationObjectLists = MM_ContinuationObjectList::newInstanceArray(env, _maxListIndex))) {
return false;
}
#if defined(J9VM_OPT_CRIU_SUPPORT)
bool
reinitializeForRestore(MM_EnvironmentBase* env)
{
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);

if (NULL == (_referenceObjectLists = MM_ReferenceObjectList::newInstanceArray(env, _maxListIndex))) {
return false;
MM_UnfinalizedObjectList *newUnfinalizedObjectLists = NULL;
MM_OwnableSynchronizerObjectList *newOwnableSynchronizerObjectLists = NULL;
MM_ContinuationObjectList *newContinuationObjectLists = NULL;
MM_ReferenceObjectList *newReferenceObjectLists = NULL;

uintptr_t newListCount = extensions->gcThreadCount;

Assert_MM_true(_maxListIndex > 0);

if (newListCount > _maxListIndex) {
if ((NULL == (newUnfinalizedObjectLists = MM_UnfinalizedObjectList::newInstanceArray(env, newListCount, _unfinalizedObjectLists, _maxListIndex)))
|| (NULL == (newOwnableSynchronizerObjectLists = MM_OwnableSynchronizerObjectList::newInstanceArray(env, newListCount, _ownableSynchronizerObjectLists, _maxListIndex)))
|| (NULL == (newContinuationObjectLists = MM_ContinuationObjectList::newInstanceArray(env, newListCount, _continuationObjectLists, _maxListIndex)))
|| (NULL == (newReferenceObjectLists = MM_ReferenceObjectList::newInstanceArray(env, newListCount, _referenceObjectLists, _maxListIndex)))
) {
goto failed;
}

tearDown(env);

_unfinalizedObjectLists = newUnfinalizedObjectLists;
_ownableSynchronizerObjectLists = newOwnableSynchronizerObjectLists;
_continuationObjectLists = newContinuationObjectLists;
_referenceObjectLists = newReferenceObjectLists;

_maxListIndex = newListCount;
}

return true;

failed:
releaseLists(env, &newUnfinalizedObjectLists, &newOwnableSynchronizerObjectLists, &newContinuationObjectLists, &newReferenceObjectLists);

return false;
}
#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */

void
kill(MM_EnvironmentBase *env)
Expand All @@ -98,24 +134,30 @@ class MM_HeapRegionDescriptorStandardExtension : public MM_BaseNonVirtual
void
tearDown(MM_EnvironmentBase *env)
{
if (NULL != _unfinalizedObjectLists) {
env->getForge()->free(_unfinalizedObjectLists);
_unfinalizedObjectLists = NULL;
releaseLists(env, &_unfinalizedObjectLists, &_ownableSynchronizerObjectLists, &_continuationObjectLists, &_referenceObjectLists);
}

void
releaseLists(MM_EnvironmentBase *env, MM_UnfinalizedObjectList **unfinalizedObjectLists, MM_OwnableSynchronizerObjectList **ownableSynchronizerObjectLists, MM_ContinuationObjectList **continuationObjectLists, MM_ReferenceObjectList **referenceObjectLists)
{
if (NULL != *unfinalizedObjectLists) {
env->getForge()->free(*unfinalizedObjectLists);
*unfinalizedObjectLists = NULL;
}

if (NULL != _ownableSynchronizerObjectLists) {
env->getForge()->free(_ownableSynchronizerObjectLists);
_ownableSynchronizerObjectLists = NULL;
if (NULL != *ownableSynchronizerObjectLists) {
env->getForge()->free(*ownableSynchronizerObjectLists);
*ownableSynchronizerObjectLists = NULL;
}

if (NULL != _continuationObjectLists) {
env->getForge()->free(_continuationObjectLists);
_continuationObjectLists = NULL;
if (NULL != *continuationObjectLists) {
env->getForge()->free(*continuationObjectLists);
*continuationObjectLists = NULL;
}

if (NULL != _referenceObjectLists) {
env->getForge()->free(_referenceObjectLists);
_referenceObjectLists = NULL;
if (NULL != *referenceObjectLists) {
env->getForge()->free(*referenceObjectLists);
*referenceObjectLists = NULL;
}
}

Expand Down

0 comments on commit ba637b2

Please sign in to comment.