diff --git a/runtime/gc_base/GCExtensions.cpp b/runtime/gc_base/GCExtensions.cpp index a6a6cc8b805..f7d0e24b76a 100644 --- a/runtime/gc_base/GCExtensions.cpp +++ b/runtime/gc_base/GCExtensions.cpp @@ -28,6 +28,7 @@ #include "j9memcategories.h" #include "j9nongenerated.h" #include "j9port.h" +#include "ModronAssertions.h" #include "util_api.h" #include "EnvironmentBase.hpp" @@ -295,3 +296,18 @@ MM_GCExtensions::registerScavenger(MM_Scavenger *scavenger) Assert_MM_true(isScavengerEnabled()); ((MM_StandardAccessBarrier *)accessBarrier)->registerScavenger(scavenger); } + +void +MM_GCExtensions::releaseNativesForContinuationObject(MM_EnvironmentBase* env, j9object_t objectPtr) +{ +#if JAVA_SPEC_VERSION >= 19 + J9VMThread *vmThread = (J9VMThread *)env->getLanguageVMThread(); + + if (verify_continuation_list == continuationListOption) { + J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(vmThread, objectPtr); + Assert_MM_true(NULL == continuation); + } else { + getJavaVM()->internalVMFunctions->freeContinuation(vmThread, objectPtr); + } +#endif /* JAVA_SPEC_VERSION >= 19 */ +} diff --git a/runtime/gc_base/GCExtensions.hpp b/runtime/gc_base/GCExtensions.hpp index a0c8a6dc16d..7201b167fa2 100644 --- a/runtime/gc_base/GCExtensions.hpp +++ b/runtime/gc_base/GCExtensions.hpp @@ -197,6 +197,13 @@ class MM_GCExtensions : public MM_GCExtensionsBase { UDATA freeSizeThresholdForSurvivor; /**< if average freeSize(freeSize/freeCount) of the region is smaller than the Threshold, the region would not be reused by collector as survivor, for balanced GC only */ bool recycleRemainders; /**< true if need to recycle TLHRemainders at the end of PGC, for balanced GC only */ + enum ContinuationListOption { + disable_continuation_list = 0, + enable_continuation_list = 1, + verify_continuation_list = 2, + }; + ContinuationListOption continuationListOption; + protected: private: protected: @@ -290,6 +297,8 @@ class MM_GCExtensions : public MM_GCExtensionsBase { MMINLINE MM_ContinuationObjectList* getContinuationObjectLists() { return continuationObjectLists; } MMINLINE void setContinuationObjectLists(MM_ContinuationObjectList* newContinuationObjectLists) { continuationObjectLists = newContinuationObjectLists; } + void releaseNativesForContinuationObject(MM_EnvironmentBase* env, j9object_t objectPtr); + /** * Create a GCExtensions object */ @@ -337,6 +346,7 @@ class MM_GCExtensions : public MM_GCExtensionsBase { , minimumFreeSizeForSurvivor(DEFAULT_SURVIVOR_MINIMUM_FREESIZE) , freeSizeThresholdForSurvivor(DEFAULT_SURVIVOR_THRESHOLD) , recycleRemainders(true) + , continuationListOption(verify_continuation_list) { _typeId = __FUNCTION__; } diff --git a/runtime/gc_base/modronapi.cpp b/runtime/gc_base/modronapi.cpp index 48f8ffca43f..3b9b9a70c30 100644 --- a/runtime/gc_base/modronapi.cpp +++ b/runtime/gc_base/modronapi.cpp @@ -1036,10 +1036,14 @@ continuationObjectCreated(J9VMThread *vmThread, j9object_t object) Assert_MM_true(NULL != object); MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread); - env->getGCEnvironment()->_continuationObjectBuffer->add(env, object); - MM_ObjectAllocationInterface *objectAllocation = env->_objectAllocationInterface; - if (NULL != objectAllocation) { - objectAllocation->getAllocationStats()->_continuationObjectCount += 1; + if (MM_GCExtensions::disable_continuation_list != MM_GCExtensions::getExtensions(env)->continuationListOption) { + + env->getGCEnvironment()->_continuationObjectBuffer->add(env, object); + MM_ObjectAllocationInterface *objectAllocation = env->_objectAllocationInterface; + + if (NULL != objectAllocation) { + objectAllocation->getAllocationStats()->_continuationObjectCount += 1; + } } return 0; } diff --git a/runtime/gc_glue_java/MarkingSchemeRootClearer.cpp b/runtime/gc_glue_java/MarkingSchemeRootClearer.cpp index 1a30c5654f0..4aca3bb3ecd 100644 --- a/runtime/gc_glue_java/MarkingSchemeRootClearer.cpp +++ b/runtime/gc_glue_java/MarkingSchemeRootClearer.cpp @@ -331,7 +331,7 @@ MM_MarkingSchemeRootClearer::scanContinuationObjects(MM_EnvironmentBase *env) } else { /* object was not previously marked */ gcEnv->_markJavaStats._continuationCleared += 1; - VM_VMHelpers::cleanupContinuationObject((J9VMThread *)env->getLanguageVMThread(), object); + _extensions->releaseNativesForContinuationObject(env, object); } object = next; } diff --git a/runtime/gc_glue_java/MetronomeDelegate.cpp b/runtime/gc_glue_java/MetronomeDelegate.cpp index 765508cfe5f..29b5a1950a3 100644 --- a/runtime/gc_glue_java/MetronomeDelegate.cpp +++ b/runtime/gc_glue_java/MetronomeDelegate.cpp @@ -1342,7 +1342,7 @@ MM_MetronomeDelegate::scanContinuationObjects(MM_EnvironmentRealtime *env) buffer->add(env, object); } else { gcEnv->_markJavaStats._continuationCleared += 1; - VM_VMHelpers::cleanupContinuationObject((J9VMThread *)env->getLanguageVMThread(), object); + _extensions->releaseNativesForContinuationObject(env, object); } object = next; diff --git a/runtime/gc_glue_java/ScavengerRootClearer.cpp b/runtime/gc_glue_java/ScavengerRootClearer.cpp index e3822d95f59..93aaaa4dd96 100644 --- a/runtime/gc_glue_java/ScavengerRootClearer.cpp +++ b/runtime/gc_glue_java/ScavengerRootClearer.cpp @@ -241,7 +241,7 @@ MM_ScavengerRootClearer::scavengeContinuationObjects(MM_EnvironmentStandard *env if (!forwardedHeader.isForwardedPointer()) { Assert_GC_true_with_message2(env, _scavenger->isObjectInEvacuateMemory(object), "Continuation object %p should be a dead object, forwardedHeader=%p\n", object, &forwardedHeader); gcEnv->_scavengerJavaStats._continuationCleared += 1; - VM_VMHelpers::cleanupContinuationObject((J9VMThread *)env->getLanguageVMThread(), object); + _extensions->releaseNativesForContinuationObject(env, object); } else { omrobjectptr_t forwardedPtr = forwardedHeader.getForwardedObject(); Assert_GC_true_with_message(env, NULL != forwardedPtr, "Continuation object %p should be forwarded\n", object); diff --git a/runtime/gc_modron_startup/mmparseXXgc.cpp b/runtime/gc_modron_startup/mmparseXXgc.cpp index 8a53d065066..28a5b50acf8 100644 --- a/runtime/gc_modron_startup/mmparseXXgc.cpp +++ b/runtime/gc_modron_startup/mmparseXXgc.cpp @@ -1515,6 +1515,20 @@ gcParseXXgcArguments(J9JavaVM *vm, char *optArg) continue; } + if (try_scan(&scan_start, "disableContinuationList")) { + extensions->continuationListOption = MM_GCExtensions::disable_continuation_list; + continue; + } + + if (try_scan(&scan_start, "enableContinuationList")) { + extensions->continuationListOption = MM_GCExtensions::enable_continuation_list; + continue; + } + + if (try_scan(&scan_start, "verifyContinuationList")) { + extensions->continuationListOption = MM_GCExtensions::verify_continuation_list; + continue; + } /* Couldn't find a match for arguments */ j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_UNKNOWN, error_scan); diff --git a/runtime/gc_vlhgc/CopyForwardScheme.cpp b/runtime/gc_vlhgc/CopyForwardScheme.cpp index 77f316eaada..74e1f69fc5c 100644 --- a/runtime/gc_vlhgc/CopyForwardScheme.cpp +++ b/runtime/gc_vlhgc/CopyForwardScheme.cpp @@ -3549,7 +3549,7 @@ MM_CopyForwardScheme::scanContinuationObjects(MM_EnvironmentVLHGC *env) if (NULL == forwardedPtr) { /* object was not previously marked, clean up */ env->_copyForwardStats._continuationCleared += 1; - VM_VMHelpers::cleanupContinuationObject((J9VMThread *)env->getLanguageVMThread(), pointer); + _extensions->releaseNativesForContinuationObject(env, pointer); } else { env->getGCEnvironment()->_continuationObjectBuffer->add(env, forwardedPtr); } diff --git a/runtime/gc_vlhgc/GlobalMarkingScheme.cpp b/runtime/gc_vlhgc/GlobalMarkingScheme.cpp index 4cc701755f3..f9e8d59da70 100644 --- a/runtime/gc_vlhgc/GlobalMarkingScheme.cpp +++ b/runtime/gc_vlhgc/GlobalMarkingScheme.cpp @@ -1111,8 +1111,8 @@ MM_GlobalMarkingScheme::scanContinuationObjects(MM_EnvironmentVLHGC *env) if (isMarked(object)) { env->getGCEnvironment()->_continuationObjectBuffer->add(env, object); } else { - VM_VMHelpers::cleanupContinuationObject((J9VMThread *)env->getLanguageVMThread(), object); env->_markVLHGCStats._continuationCleared += 1; + _extensions->releaseNativesForContinuationObject(env, object); } object = next; } diff --git a/runtime/oti/VMHelpers.hpp b/runtime/oti/VMHelpers.hpp index 457f7a5949a..ead29009979 100644 --- a/runtime/oti/VMHelpers.hpp +++ b/runtime/oti/VMHelpers.hpp @@ -2157,14 +2157,6 @@ class VM_VMHelpers return needScan; } - static VMINLINE void - cleanupContinuationObject(J9VMThread *vmThread, J9Object *objectPtr) - { -#if JAVA_SPEC_VERSION >= 19 - vmThread->javaVM->internalVMFunctions->freeContinuation(vmThread, objectPtr); -#endif /* JAVA_SPEC_VERSION >= 19 */ - } - static VMINLINE UDATA setVMState(J9VMThread *currentThread, UDATA newState) {