From 7411dc0fd01751b465416a16b444ff454d8cdf7d Mon Sep 17 00:00:00 2001 From: lhu Date: Wed, 20 Nov 2024 13:47:55 -0500 Subject: [PATCH] Update RealtimeAccessBarrier to use common apis for copy arrayCritical - Update RealtimeAccessBarrier to use opyArrayCritical, copyBackArrayCritical, copyStringCritical and freeStringCritical common functions (in ObjectAccessBarrier baseclass) to replace similar code in class RealtimeAccessBarrier. - output warning message if off-heap is enabled in gcpolicy:metronome. Signed-off-by: lhu --- runtime/gc_realtime/ConfigurationRealtime.cpp | 13 ++- runtime/gc_realtime/RealtimeAccessBarrier.cpp | 104 +++--------------- runtime/nls/j9gc/j9modron.nls | 14 +++ 3 files changed, 43 insertions(+), 88 deletions(-) diff --git a/runtime/gc_realtime/ConfigurationRealtime.cpp b/runtime/gc_realtime/ConfigurationRealtime.cpp index 8f9f1ae5be7..534b132eed5 100644 --- a/runtime/gc_realtime/ConfigurationRealtime.cpp +++ b/runtime/gc_realtime/ConfigurationRealtime.cpp @@ -27,6 +27,7 @@ #include "omr.h" #include "omrcfg.h" +#include "modronnls.h" #include "ConfigurationRealtime.hpp" @@ -106,7 +107,17 @@ MM_ConfigurationRealtime::tearDown(MM_EnvironmentBase* env) MM_Heap * MM_ConfigurationRealtime::createHeapWithManager(MM_EnvironmentBase *env, uintptr_t heapBytesRequested, MM_HeapRegionManager *regionManager) { - return MM_HeapVirtualMemory::newInstance(env, env->getExtensions()->heapAlignment, heapBytesRequested, regionManager); + MM_GCExtensionsBase *extensions = env->getExtensions(); + +#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) + PORT_ACCESS_FROM_ENVIRONMENT(env); + + if (extensions->isVirtualLargeObjectHeapRequested) { + j9nls_printf(PORTLIB, J9NLS_WARNING, J9NLS_GC_OPTIONS_VIRTUAL_LARGE_OBJECT_HEAP_NOT_SUPPORTED_WARN, "metronome"); + } +#endif /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */ + + return MM_HeapVirtualMemory::newInstance(env, extensions->heapAlignment, heapBytesRequested, regionManager); } MM_MemorySpace * diff --git a/runtime/gc_realtime/RealtimeAccessBarrier.cpp b/runtime/gc_realtime/RealtimeAccessBarrier.cpp index f275b9e498f..eb242e79b34 100644 --- a/runtime/gc_realtime/RealtimeAccessBarrier.cpp +++ b/runtime/gc_realtime/RealtimeAccessBarrier.cpp @@ -261,7 +261,7 @@ MM_RealtimeAccessBarrier::validateWriteBarrier(J9VMThread *vmThread, J9Object *d case GC_ObjectModel::SCAN_CLASSLOADER_OBJECT: case GC_ObjectModel::SCAN_REFERENCE_MIXED_OBJECT: { - intptr_t slotIndex = GC_SlotObject::subtractSlotAddresses(dstAddress, (fj9object_t*)dstObject, compressed); + intptr_t slotIndex = GC_SlotObject::subtractSlotAddresses(dstAddress, (fj9object_t *)dstObject, compressed); if (slotIndex < 0) { j9tty_printf(PORTLIB, "validateWriteBarrier: slotIndex is negative dstAddress %d and dstObject %d\n", dstAddress, dstObject); } @@ -278,10 +278,10 @@ MM_RealtimeAccessBarrier::validateWriteBarrier(J9VMThread *vmThread, J9Object *d case GC_ObjectModel::SCAN_POINTER_ARRAY_OBJECT: { MM_HeapRegionManager *regionManager = MM_GCExtensions::getExtensions(javaVM)->getHeap()->getHeapRegionManager(); - GC_ArrayletObjectModel::ArrayLayout layout = _extensions->indexableObjectModel.getArrayLayout((J9IndexableObject*)dstObject); + GC_ArrayletObjectModel::ArrayLayout layout = _extensions->indexableObjectModel.getArrayLayout((J9IndexableObject *)dstObject); switch (layout) { case GC_ArrayletObjectModel::InlineContiguous: { - UDATA** arrayletPtr = (UDATA**)(((J9IndexableObject*)dstObject) + 1); + UDATA** arrayletPtr = (UDATA **)(((J9IndexableObject *)dstObject) + 1); UDATA* dataStart = *arrayletPtr; UDATA* dataEnd = dataStart + _extensions->indexableObjectModel.getSizeInElements((J9IndexableObject*)dstObject); if ((UDATA*)dstAddress < dataStart || (UDATA*)dstAddress >= dataEnd) { @@ -448,39 +448,25 @@ void* MM_RealtimeAccessBarrier::jniGetPrimitiveArrayCritical(J9VMThread* vmThread, jarray array, jboolean *isCopy) { void *data = NULL; - J9JavaVM *javaVM = vmThread->javaVM; - J9InternalVMFunctions *functions = javaVM->internalVMFunctions; - J9IndexableObject *arrayObject = (J9IndexableObject*)J9_JNI_UNWRAP_REFERENCE(array); + J9IndexableObject *arrayObject = (J9IndexableObject *)J9_JNI_UNWRAP_REFERENCE(array); bool shouldCopy = false; - if((javaVM->runtimeFlags & J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL) == J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL) { + if (J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL == (vmThread->javaVM->runtimeFlags & J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL)) { shouldCopy = true; } else if (!_extensions->indexableObjectModel.isInlineContiguousArraylet(arrayObject)) { /* an array having discontiguous extents is another reason to force the critical section to be a copy */ shouldCopy = true; } - if(shouldCopy) { + if (shouldCopy) { VM_VMAccess::inlineEnterVMFromJNI(vmThread); - GC_ArrayObjectModel* indexableObjectModel = &_extensions->indexableObjectModel; - I_32 sizeInElements = (I_32)indexableObjectModel->getSizeInElements(arrayObject); - UDATA sizeInBytes = indexableObjectModel->getDataSizeInBytes(arrayObject); - data = functions->jniArrayAllocateMemoryFromThread(vmThread, sizeInBytes); - if(NULL == data) { - functions->setNativeOutOfMemoryError(vmThread, 0, 0); // better error message here? - } else { - indexableObjectModel->memcpyFromArray(data, arrayObject, 0, sizeInElements); - if(NULL != isCopy) { - *isCopy = JNI_TRUE; - } - } - vmThread->jniCriticalCopyCount += 1; + copyArrayCritical(vmThread, &data, arrayObject, isCopy); VM_VMAccess::inlineExitVMToJNI(vmThread); } else { // acquire access and return a direct pointer MM_JNICriticalRegion::enterCriticalRegion(vmThread, false); data = (void *)_extensions->indexableObjectModel.getDataPointerForContiguous(arrayObject); - if(NULL != isCopy) { + if (NULL != isCopy) { *isCopy = JNI_FALSE; } } @@ -490,38 +476,18 @@ MM_RealtimeAccessBarrier::jniGetPrimitiveArrayCritical(J9VMThread* vmThread, jar void MM_RealtimeAccessBarrier::jniReleasePrimitiveArrayCritical(J9VMThread* vmThread, jarray array, void * elems, jint mode) { - J9JavaVM *javaVM = vmThread->javaVM; - J9InternalVMFunctions *functions = javaVM->internalVMFunctions; - - J9IndexableObject *arrayObject = (J9IndexableObject*)J9_JNI_UNWRAP_REFERENCE(array); + J9IndexableObject *arrayObject = (J9IndexableObject *)J9_JNI_UNWRAP_REFERENCE(array); bool shouldCopy = false; - if((javaVM->runtimeFlags & J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL) == J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL) { + if (J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL == (vmThread->javaVM->runtimeFlags & J9_RUNTIME_ALWAYS_COPY_JNI_CRITICAL)) { shouldCopy = true; } else if (!_extensions->indexableObjectModel.isInlineContiguousArraylet(arrayObject)) { /* an array having discontiguous extents is another reason to force the critical section to be a copy */ shouldCopy = true; } - if(shouldCopy) { + if (shouldCopy) { VM_VMAccess::inlineEnterVMFromJNI(vmThread); - if(JNI_ABORT != mode) { - GC_ArrayObjectModel* indexableObjectModel = &_extensions->indexableObjectModel; - I_32 sizeInElements = (I_32)indexableObjectModel->getSizeInElements(arrayObject); - _extensions->indexableObjectModel.memcpyToArray(arrayObject, 0, sizeInElements, elems); - } - - // Commit means copy the data but do not free the buffer. - // All other modes free the buffer. - if(JNI_COMMIT != mode) { - functions->jniArrayFreeMemoryFromThread(vmThread, elems); - } - - if(vmThread->jniCriticalCopyCount > 0) { - vmThread->jniCriticalCopyCount -= 1; - } else { - Assert_MM_invalidJNICall(); - } - + copyBackArrayCritical(vmThread, elems, &arrayObject, mode); VM_VMAccess::inlineExitVMToJNI(vmThread); } else { /* @@ -529,7 +495,7 @@ MM_RealtimeAccessBarrier::jniReleasePrimitiveArrayCritical(J9VMThread* vmThread, * This trace point will be generated if object has been moved or passed value of elems is corrupted */ void *data = (void *)_extensions->indexableObjectModel.getDataPointerForContiguous(arrayObject); - if(elems != data) { + if (elems != data) { Trc_MM_JNIReleasePrimitiveArrayCritical_invalid(vmThread, arrayObject, elems, data); } @@ -541,8 +507,6 @@ const jchar* MM_RealtimeAccessBarrier::jniGetStringCritical(J9VMThread* vmThread, jstring str, jboolean *isCopy) { jchar *data = NULL; - J9JavaVM *javaVM = vmThread->javaVM; - J9InternalVMFunctions *functions = javaVM->internalVMFunctions; bool isCompressed = false; bool shouldCopy = false; bool hasVMAccess = false; @@ -554,42 +518,17 @@ MM_RealtimeAccessBarrier::jniGetStringCritical(J9VMThread* vmThread, jstring str if (shouldCopy) { J9Object *stringObject = (J9Object*)J9_JNI_UNWRAP_REFERENCE(str); - J9IndexableObject *valueObject = (J9IndexableObject*)J9VMJAVALANGSTRING_VALUE(vmThread, stringObject); - jint length = J9VMJAVALANGSTRING_LENGTH(vmThread, stringObject); - UDATA sizeInBytes = length * sizeof(jchar); + J9IndexableObject *valueObject = (J9IndexableObject *)J9VMJAVALANGSTRING_VALUE(vmThread, stringObject); if (IS_STRING_COMPRESSED(vmThread, stringObject)) { isCompressed = true; } - data = (jchar*)functions->jniArrayAllocateMemoryFromThread(vmThread, sizeInBytes); - if (NULL == data) { - functions->setNativeOutOfMemoryError(vmThread, 0, 0); // better error message here? - } else { - GC_ArrayObjectModel* indexableObjectModel = &_extensions->indexableObjectModel; - if (isCompressed) { - jint i; - - for (i = 0; i < length; i++) { - data[i] = (jchar)(U_8)J9JAVAARRAYOFBYTE_LOAD(vmThread, (j9object_t)valueObject, i); - } - } else { - if (J9_ARE_ANY_BITS_SET(javaVM->runtimeFlags, J9_RUNTIME_STRING_BYTE_ARRAY)) { - // This API determines the stride based on the type of valueObject so in the [B case we must passin the length in bytes - indexableObjectModel->memcpyFromArray(data, valueObject, 0, (I_32)sizeInBytes); - } else { - indexableObjectModel->memcpyFromArray(data, valueObject, 0, length); - } - } - if (NULL != isCopy) { - *isCopy = JNI_TRUE; - } - } - vmThread->jniCriticalCopyCount += 1; + copyStringCritical(vmThread, &data, valueObject, stringObject, isCopy, isCompressed); } else { // acquire access and return a direct pointer MM_JNICriticalRegion::enterCriticalRegion(vmThread, hasVMAccess); J9Object *stringObject = (J9Object*)J9_JNI_UNWRAP_REFERENCE(str); - J9IndexableObject *valueObject = (J9IndexableObject*)J9VMJAVALANGSTRING_VALUE(vmThread, stringObject); + J9IndexableObject *valueObject = (J9IndexableObject *)J9VMJAVALANGSTRING_VALUE(vmThread, stringObject); data = (jchar*)_extensions->indexableObjectModel.getDataPointerForContiguous(valueObject); @@ -606,8 +545,6 @@ MM_RealtimeAccessBarrier::jniGetStringCritical(J9VMThread* vmThread, jstring str void MM_RealtimeAccessBarrier::jniReleaseStringCritical(J9VMThread* vmThread, jstring str, const jchar* elems) { - J9JavaVM *javaVM = vmThread->javaVM; - J9InternalVMFunctions *functions = javaVM->internalVMFunctions; bool hasVMAccess = false; bool shouldCopy = false; @@ -615,14 +552,7 @@ MM_RealtimeAccessBarrier::jniReleaseStringCritical(J9VMThread* vmThread, jstring shouldCopy = true; if (shouldCopy) { - // String data is not copied back - functions->jniArrayFreeMemoryFromThread(vmThread, (void*)elems); - - if(vmThread->jniCriticalCopyCount > 0) { - vmThread->jniCriticalCopyCount -= 1; - } else { - Assert_MM_invalidJNICall(); - } + freeStringCritical(vmThread, elems); } else { // direct pointer, just drop access MM_JNICriticalRegion::exitCriticalRegion(vmThread, hasVMAccess); diff --git a/runtime/nls/j9gc/j9modron.nls b/runtime/nls/j9gc/j9modron.nls index ee774701f41..93f6a01aecd 100644 --- a/runtime/nls/j9gc/j9modron.nls +++ b/runtime/nls/j9gc/j9modron.nls @@ -1008,3 +1008,17 @@ J9NLS_CHECKPOINTGCTHREAD_VALUE_MUST_BE_AT_MOST_HEURISTIC_GCTHREAD_VALUE_WARN.use J9NLS_CHECKPOINTGCTHREAD_VALUE_MUST_BE_AT_MOST_HEURISTIC_GCTHREAD_VALUE_WARN.sample_input_1=6 J9NLS_CHECKPOINTGCTHREAD_VALUE_MUST_BE_AT_MOST_HEURISTIC_GCTHREAD_VALUE_WARN.sample_input_2=4 # END NON-TRANSLATABLE + +J9NLS_GC_OPTIONS_VIRTUAL_LARGE_OBJECT_HEAP_NOT_SUPPORTED_WARN=Unsupported -XX:enableVirtualLargeObjectHeap option with -Xgcpolicy:%s will be ignored. +# START NON-TRANSLATABLE +J9NLS_GC_OPTIONS_VIRTUAL_LARGE_OBJECT_HEAP_NOT_SUPPORTED_WARN.explanation=-XX:enableVirtualLargeObjectHeap is currently only supported with -Xgcpolicy:balanced. +J9NLS_GC_OPTIONS_VIRTUAL_LARGE_OBJECT_HEAP_NOT_SUPPORTED_WARN.system_action=The JVM ignores the -XX:enableVirtualLargeObjectHeap option. +J9NLS_GC_OPTIONS_VIRTUAL_LARGE_OBJECT_HEAP_NOT_SUPPORTED_WARN.user_response=None +# END NON-TRANSLATABLE + +J9NLS_GC_OPTIONS_ARRAYLET_DOUBLE_MAPPING_NOT_SUPPORTED_WARN=Unsupported -Xgc:enableArrayletDoubleMapping option with -Xgcpolicy:%s will be ignored. +# START NON-TRANSLATABLE +J9NLS_GC_OPTIONS_ARRAYLET_DOUBLE_MAPPING_NOT_SUPPORTED_WARN.explanation=-Xgc:enableArrayletDoubleMapping is currently only supported with -Xgcpolicy:balanced. +J9NLS_GC_OPTIONS_ARRAYLET_DOUBLE_MAPPING_NOT_SUPPORTED_WARN.system_action=The JVM ignores the -Xgc:enableArrayletDoubleMapping option. +J9NLS_GC_OPTIONS_ARRAYLET_DOUBLE_MAPPING_NOT_SUPPORTED_WARN.user_response=Refer to the OpenJ9 documentation for -Xgc:enableArrayletDoubleMapping. +# END NON-TRANSLATABLE