Skip to content

Commit

Permalink
Merge pull request #19388 from LinHu2016/v0.45.0-release
Browse files Browse the repository at this point in the history
(0.45) Fixup stack references of unmounted continuation for scavenge backout
  • Loading branch information
pshipton committed Apr 26, 2024
2 parents 349ff6e + 13a432d commit 578a50a
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 94 deletions.
5 changes: 5 additions & 0 deletions runtime/gc_base/RootScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,11 @@ MM_RootScanner::scanClearable(MM_EnvironmentBase *env)
return ;
}

/* Just completed last phase that may have done any object scanning (or copied objects if a copying collector).
* Collectors have a chance to invoke specific processing and checks.
*/
completedObjectScanPhasesCheckpoint();

/*
* clear the following private references once resurrection is completed
*/
Expand Down
5 changes: 5 additions & 0 deletions runtime/gc_base/RootScanner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,11 @@ class MM_RootScanner : public MM_BaseVirtual
virtual CompletePhaseCode scanUnfinalizedObjectsComplete(MM_EnvironmentBase *env);
#endif /* J9VM_GC_FINALIZATION */

/**
* During clearabble processing, invoke specific processing/checks after last known phase that scans (and copies) objects.
*/
virtual void completedObjectScanPhasesCheckpoint() {}

/**
* @todo Provide function documentation
*/
Expand Down
101 changes: 14 additions & 87 deletions runtime/gc_glue_java/ScavengerBackOutScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ MM_ScavengerBackOutScanner::scanAllSlots(MM_EnvironmentBase *env)
if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
for (uintptr_t i = 0; i < regionExtension->_maxListIndex; i++) {
MM_ReferenceObjectList *list = &regionExtension->_referenceObjectLists[i];
list->resetLists();
regionExtension->_referenceObjectLists[i].resetLists();
}
}
}
Expand All @@ -61,14 +60,24 @@ MM_ScavengerBackOutScanner::scanAllSlots(MM_EnvironmentBase *env)
MM_RootScanner::scanAllSlots(env);

if (!_extensions->isConcurrentScavengerEnabled()) {
/* Back out Ownable Synchronizer Processing */
/* Back out Ownable Synchronizer and Continuation Processing */
MM_HeapRegionDescriptorStandard *region = NULL;
GC_HeapRegionIteratorStandard regionIterator(_extensions->heapRegionManager);
while (NULL != (region = regionIterator.nextRegion())) {
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
for (uintptr_t i = 0; i < regionExtension->_maxListIndex; i++) {
MM_OwnableSynchronizerObjectList *list = &regionExtension->_ownableSynchronizerObjectLists[i];
list->backoutList();
/**
* For Ownable Synchronizers lists, back out all of regions (includes tenure region, which is backed up during startProcessing).
* Tenure list might have gotten new elements during main Scavenge phase and it is important to restore the list, since it will be iterated later during Marking Clearable phase.
*/
regionExtension->_ownableSynchronizerObjectLists[i].backoutList();
if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {
/**
* For Continuation lists, Consistent with startProcessing that was earlier (in this GC cycle) called only on NEW regions.
* Tenure list cannot get new elements, since they are added only during Scavenge Clearable phase that cannot be reached if there was a Scavenge abort.
*/
regionExtension->_continuationObjectLists[i].backoutList();
}
}
}
}
Expand Down Expand Up @@ -319,86 +328,4 @@ MM_ScavengerBackOutScanner::backoutUnfinalizedObjects(MM_EnvironmentStandard *en
env->getGCEnvironment()->_unfinalizedObjectBuffer->flush(env);
}
#endif /* J9VM_GC_FINALIZATION */

void
MM_ScavengerBackOutScanner::backoutContinuationObjects(MM_EnvironmentStandard *env)
{
MM_Heap *heap = _extensions->heap;
MM_HeapRegionManager *regionManager = heap->getHeapRegionManager();
MM_HeapRegionDescriptorStandard *region = NULL;
bool const compressed = _extensions->compressObjectReferences();

GC_HeapRegionIteratorStandard regionIterator(regionManager);
while (NULL != (region = regionIterator.nextRegion())) {
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
for (uintptr_t i = 0; i < regionExtension->_maxListIndex; i++) {
MM_ContinuationObjectList *list = &regionExtension->_continuationObjectLists[i];
list->startProcessing();
}
}

#if defined(OMR_GC_CONCURRENT_SCAVENGER)
if (_extensions->isConcurrentScavengerEnabled()) {
GC_HeapRegionIteratorStandard regionIterator2(regionManager);
while (NULL != (region = regionIterator2.nextRegion())) {
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
for (uintptr_t i = 0; i < regionExtension->_maxListIndex; i++) {
MM_ContinuationObjectList *list = &regionExtension->_continuationObjectLists[i];
if (!list->wasEmpty()) {
omrobjectptr_t object = list->getPriorList();
while (NULL != object) {
MM_ForwardedHeader forwardHeader(object, compressed);
omrobjectptr_t forwardPtr = forwardHeader.getNonStrictForwardedObject();
if (NULL != forwardPtr) {
if (forwardHeader.isSelfForwardedPointer()) {
forwardHeader.restoreSelfForwardedPointer();
} else {
object = forwardPtr;
}
}

omrobjectptr_t next = _extensions->accessBarrier->getContinuationLink(object);
env->getGCEnvironment()->_continuationObjectBuffer->add(env, object);

object = next;
}
}
}
}
} else
#endif /* OMR_GC_CONCURRENT_SCAVENGER */
{
GC_HeapRegionIteratorStandard regionIterator2(regionManager);
while (NULL != (region = regionIterator2.nextRegion())) {
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
for (uintptr_t i = 0; i < regionExtension->_maxListIndex; i++) {
MM_ContinuationObjectList *list = &regionExtension->_continuationObjectLists[i];
if (!list->wasEmpty()) {
omrobjectptr_t object = list->getPriorList();
while (NULL != object) {
omrobjectptr_t next = NULL;
MM_ForwardedHeader forwardHeader(object, compressed);
Assert_MM_false(forwardHeader.isForwardedPointer());
if (forwardHeader.isReverseForwardedPointer()) {
omrobjectptr_t originalObject = forwardHeader.getReverseForwardedPointer();
Assert_MM_true(NULL != originalObject);
next = _extensions->accessBarrier->getContinuationLink(originalObject);
env->getGCEnvironment()->_continuationObjectBuffer->add(env, originalObject);
} else {
next = _extensions->accessBarrier->getContinuationLink(object);
env->getGCEnvironment()->_continuationObjectBuffer->add(env, object);
}

object = next;
}
}
}
}
}

/* restore everything to a flushed state before exiting */
env->getGCEnvironment()->_continuationObjectBuffer->flush(env);

/* Done backout */
}
#endif /* defined(OMR_GC_MODRON_SCAVENGER) */
12 changes: 5 additions & 7 deletions runtime/gc_glue_java/ScavengerBackOutScanner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class MM_ScavengerBackOutScanner : public MM_RootScanner
void backoutUnfinalizedObjects(MM_EnvironmentStandard *env);
void backoutFinalizableObjects(MM_EnvironmentStandard *env);
#endif
void backoutContinuationObjects(MM_EnvironmentStandard *env);

public:
MM_ScavengerBackOutScanner(MM_EnvironmentBase *env, bool singleThread, MM_Scavenger *scavenger)
Expand Down Expand Up @@ -118,12 +117,11 @@ class MM_ScavengerBackOutScanner : public MM_RootScanner

/* empty, move ownable synchronizer backout processing in scanAllSlots() */
virtual void scanOwnableSynchronizerObjects(MM_EnvironmentBase *env) {}
virtual void scanContinuationObjects(MM_EnvironmentBase *env)
{
reportScanningStarted(RootScannerEntity_ContinuationObjects);
backoutContinuationObjects(MM_EnvironmentStandard::getEnvironment(env));
reportScanningEnded(RootScannerEntity_ContinuationObjects);
}
/**
* empty, move continuation backout processing in scanAllSlots(), scavenger abort would never happen after continuationObjectList processing
* so only need to backout list._head from _priorHead
*/
virtual void scanContinuationObjects(MM_EnvironmentBase *env) {}
};
#endif /* defined(OMR_GC_MODRON_SCAVENGER) */

Expand Down
11 changes: 11 additions & 0 deletions runtime/gc_glue_java/ScavengerDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,17 @@ MM_ScavengerDelegate::reverseForwardedObject(MM_EnvironmentBase *env, MM_Forward
if (NULL != finalizeLinkAddress) {
barrier->setFinalizeLink(objectPtr, barrier->getFinalizeLink(fwdObjectPtr));
}

/* fixup the references in the continuation native StackSlots */
switch (_extensions->objectModel.getScanType(forwardedClass)) {

case GC_ObjectModel::SCAN_CONTINUATION_OBJECT:
scanContinuationNativeSlots(MM_EnvironmentStandard::getEnvironment(env), objectPtr, SCAN_REASON_BACKOUT);
break;
default:
break;
}

}
}

Expand Down
5 changes: 5 additions & 0 deletions runtime/gc_glue_java/ScavengerRootClearer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@ class MM_ScavengerRootClearer : public MM_RootScanner
_scavenger->pruneRememberedSet(MM_EnvironmentStandard::getEnvironment(env));
reportScanningEnded(RootScannerEntity_RememberedSet);
}

virtual void completedObjectScanPhasesCheckpoint() {
Assert_MM_false(_extensions->isScavengerBackOutFlagRaised());
}

};
#endif /* defined(OMR_GC_MODRON_SCAVENGER) */
#endif /* SCAVENGERROOTCLEARER_HPP_ */

0 comments on commit 578a50a

Please sign in to comment.