diff --git a/runtime/jcl/common/mgmtmemory.c b/runtime/jcl/common/mgmtmemory.c index 1d048dd51ee..f8885aa3254 100644 --- a/runtime/jcl/common/mgmtmemory.c +++ b/runtime/jcl/common/mgmtmemory.c @@ -32,7 +32,7 @@ static UDATA getIndexFromGCID(J9JavaLangManagementData *mgmt, UDATA id); jobject JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getHeapMemoryUsageImpl(JNIEnv *env, jobject beanInstance, jclass memoryUsage, jobject memUsageConstructor) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; jlong used = 0; jlong committed = 0; jmethodID ctor = NULL; @@ -51,7 +51,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getHeapMemoryUsageIm jobject JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getNonHeapMemoryUsageImpl(JNIEnv *env, jobject beanInstance, jclass memoryUsage, jobject memUsageConstructor) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; jlong used = 0; jlong committed = 0; @@ -76,25 +76,77 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getNonHeapMemoryUsag omrthread_monitor_enter(javaVM->classTableMutex); classLoader = javaVM->internalVMFunctions->allClassLoadersStartDo(&walkState, javaVM, 0); while (NULL != classLoader) { - UDATA *udataFreeListBlock = classLoader->ramClassUDATABlockFreeList; - J9RAMClassFreeListBlock *tinyFreeListBlock = classLoader->ramClassTinyBlockFreeList; - J9RAMClassFreeListBlock *smallFreeListBlock = classLoader->ramClassSmallBlockFreeList; - J9RAMClassFreeListBlock *largeFreeListBlock = classLoader->ramClassLargeBlockFreeList; - while (NULL != udataFreeListBlock) { - used -= sizeof(UDATA); - udataFreeListBlock = *(UDATA **) udataFreeListBlock; + J9RAMClassUDATABlockFreeList *ramClassUDATABlocksPtr = &classLoader->ramClassUDATABlocks; + J9RAMClassFreeLists *sub4gBlockPtr = &classLoader->sub4gBlock; + J9RAMClassFreeLists *frequentlyAccessedBlockPtr = &classLoader->frequentlyAccessedBlock; + J9RAMClassFreeLists *inFrequentlyAccessedBlockPtr = &classLoader->inFrequentlyAccessedBlock; + if (NULL != ramClassUDATABlocksPtr) { + UDATA *ramClassSub4gUDATABlockFreeListPtr = ramClassUDATABlocksPtr->ramClassSub4gUDATABlockFreeList; + UDATA *ramClassFreqUDATABlockFreeListPtr = ramClassUDATABlocksPtr->ramClassFreqUDATABlockFreeList; + UDATA *ramClassInFreqUDATABlockFreeListPtr = ramClassUDATABlocksPtr->ramClassInFreqUDATABlockFreeList; + while (NULL != ramClassSub4gUDATABlockFreeListPtr) { + used -= sizeof(UDATA); + ramClassSub4gUDATABlockFreeListPtr = *(UDATA **)ramClassSub4gUDATABlockFreeListPtr; + } + while (NULL != ramClassFreqUDATABlockFreeListPtr) { + used -= sizeof(UDATA); + ramClassFreqUDATABlockFreeListPtr = *(UDATA **)ramClassFreqUDATABlockFreeListPtr; + } + while (NULL != ramClassInFreqUDATABlockFreeListPtr) { + used -= sizeof(UDATA); + ramClassInFreqUDATABlockFreeListPtr = *(UDATA **)ramClassInFreqUDATABlockFreeListPtr; + } } - while (NULL != tinyFreeListBlock) { - used -= tinyFreeListBlock->size; - tinyFreeListBlock = tinyFreeListBlock->nextFreeListBlock; + if (NULL != sub4gBlockPtr) { + J9RAMClassFreeListBlock *ramClassTinyBlockFreeListPtr = sub4gBlockPtr->ramClassTinyBlockFreeList; + J9RAMClassFreeListBlock *ramClassSmallBlockFreeListPtr = sub4gBlockPtr->ramClassSmallBlockFreeList; + J9RAMClassFreeListBlock *ramClassLargeBlockFreeListPtr = sub4gBlockPtr->ramClassLargeBlockFreeList; + while (NULL != ramClassTinyBlockFreeListPtr) { + used -= ramClassTinyBlockFreeListPtr->size; + ramClassTinyBlockFreeListPtr = ramClassTinyBlockFreeListPtr->nextFreeListBlock; + } + while (NULL != ramClassSmallBlockFreeListPtr) { + used -= ramClassSmallBlockFreeListPtr->size; + ramClassSmallBlockFreeListPtr = ramClassSmallBlockFreeListPtr->nextFreeListBlock; + } + while (NULL != ramClassLargeBlockFreeListPtr) { + used -= ramClassLargeBlockFreeListPtr->size; + ramClassLargeBlockFreeListPtr = ramClassLargeBlockFreeListPtr->nextFreeListBlock; + } } - while (NULL != smallFreeListBlock) { - used -= smallFreeListBlock->size; - smallFreeListBlock = smallFreeListBlock->nextFreeListBlock; + if (NULL != frequentlyAccessedBlockPtr) { + J9RAMClassFreeListBlock *ramClassTinyBlockFreeListPtr = frequentlyAccessedBlockPtr->ramClassTinyBlockFreeList; + J9RAMClassFreeListBlock *ramClassSmallBlockFreeListPtr = frequentlyAccessedBlockPtr->ramClassSmallBlockFreeList; + J9RAMClassFreeListBlock *ramClassLargeBlockFreeListPtr = frequentlyAccessedBlockPtr->ramClassLargeBlockFreeList; + while (NULL != ramClassTinyBlockFreeListPtr) { + used -= ramClassTinyBlockFreeListPtr->size; + ramClassTinyBlockFreeListPtr = ramClassTinyBlockFreeListPtr->nextFreeListBlock; + } + while (NULL != ramClassSmallBlockFreeListPtr) { + used -= ramClassSmallBlockFreeListPtr->size; + ramClassSmallBlockFreeListPtr = ramClassSmallBlockFreeListPtr->nextFreeListBlock; + } + while (NULL != ramClassLargeBlockFreeListPtr) { + used -= ramClassLargeBlockFreeListPtr->size; + ramClassLargeBlockFreeListPtr = ramClassLargeBlockFreeListPtr->nextFreeListBlock; + } } - while (NULL != largeFreeListBlock) { - used -= largeFreeListBlock->size; - largeFreeListBlock = largeFreeListBlock->nextFreeListBlock; + if (NULL != inFrequentlyAccessedBlockPtr) { + J9RAMClassFreeListBlock *ramClassTinyBlockFreeListPtr = inFrequentlyAccessedBlockPtr->ramClassTinyBlockFreeList; + J9RAMClassFreeListBlock *ramClassSmallBlockFreeListPtr = inFrequentlyAccessedBlockPtr->ramClassSmallBlockFreeList; + J9RAMClassFreeListBlock *ramClassLargeBlockFreeListPtr = inFrequentlyAccessedBlockPtr->ramClassLargeBlockFreeList; + while (NULL != ramClassTinyBlockFreeListPtr) { + used -= ramClassTinyBlockFreeListPtr->size; + ramClassTinyBlockFreeListPtr = ramClassTinyBlockFreeListPtr->nextFreeListBlock; + } + while (NULL != ramClassSmallBlockFreeListPtr) { + used -= ramClassSmallBlockFreeListPtr->size; + ramClassSmallBlockFreeListPtr = ramClassSmallBlockFreeListPtr->nextFreeListBlock; + } + while (NULL != ramClassLargeBlockFreeListPtr) { + used -= ramClassLargeBlockFreeListPtr->size; + ramClassLargeBlockFreeListPtr = ramClassLargeBlockFreeListPtr->nextFreeListBlock; + } } classLoader = javaVM->internalVMFunctions->allClassLoadersNextDo(&walkState); } @@ -166,7 +218,7 @@ jint JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getObjectPendingFinalizationCountImpl(JNIEnv *env, jobject beanInstance) { #if defined(J9VM_GC_FINALIZATION) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; return (jint)javaVM->memoryManagerFunctions->j9gc_get_objects_pending_finalization_count(javaVM); #else return (jint)0; @@ -176,7 +228,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getObjectPendingFina jboolean JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_isVerboseImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; return VERBOSE_GC == (VERBOSE_GC & javaVM->verboseLevel) ; } @@ -184,7 +236,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_isVerboseImpl(JNIEnv void JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setVerboseImpl(JNIEnv *env, jobject beanInstance, jboolean flag) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9VerboseSettings verboseOptions; memset(&verboseOptions, 0, sizeof(J9VerboseSettings)); @@ -197,7 +249,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setVerboseImpl(JNIEn void JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryManagers(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; jclass memBean = NULL; jstring childName = NULL; jmethodID helperID = NULL; @@ -234,7 +286,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryManagers } for (idx = 0; idx < mgmt->supportedCollectors; ++idx) { - id = (jint) mgmt->garbageCollectors[idx].id; + id = (jint)mgmt->garbageCollectors[idx].id; childName = (*env)->NewStringUTF(env, mgmt->garbageCollectors[idx].name); if (NULL == childName) { return; @@ -247,7 +299,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryManagers void JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryPools(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; jclass memBean = NULL; jstring childName = NULL; jmethodID helperID = NULL; @@ -267,7 +319,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryPools(JN /* Heap Memory Pools */ for (idx = 0; idx < mgmt->supportedMemoryPools; ++idx) { - id = (jint) mgmt->memoryPools[idx].id; + id = (jint)mgmt->memoryPools[idx].id; childName = (*env)->NewStringUTF(env, mgmt->memoryPools[idx].name); if (NULL == childName) { return; @@ -281,7 +333,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryPools(JN /* NonHeap Memory Pools */ for (idx = 0; idx < mgmt->supportedNonHeapMemoryPools; ++idx) { - id = (jint) mgmt->nonHeapMemoryPools[idx].id; + id = (jint)mgmt->nonHeapMemoryPools[idx].id; childName = (*env)->NewStringUTF(env, mgmt->nonHeapMemoryPools[idx].name); if (NULL == childName) { return; @@ -297,7 +349,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryPools(JN jlong JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMaxHeapSizeLimitImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; return javaVM->memoryManagerFunctions->j9gc_get_maximum_heap_size(javaVM); } @@ -305,7 +357,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMaxHeapSizeLimitI jlong JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMaxHeapSizeImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; UDATA softmx = javaVM->memoryManagerFunctions->j9gc_get_softmx(javaVM); /* if no softmx has been set, report -Xmx instead as it is the current max heap size */ @@ -318,7 +370,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMaxHeapSizeImpl(J jlong JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMinHeapSizeImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; return javaVM->memoryManagerFunctions->j9gc_get_initial_heap_size(javaVM); } @@ -326,7 +378,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMinHeapSizeImpl(J void JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setMaxHeapSizeImpl(JNIEnv *env, jobject beanInstance, jlong newsoftmx) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; javaVM->memoryManagerFunctions->j9gc_set_softmx(javaVM, (UDATA)newsoftmx); } @@ -337,7 +389,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheS jboolean ret = JNI_FALSE; #if defined(J9VM_OPT_SHARED_CLASSES) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; if (javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)value, -1, -1, -1, -1)) { @@ -354,7 +406,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheM jboolean ret = JNI_FALSE; #if defined(J9VM_OPT_SHARED_CLASSES) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; if (javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)-1, (I_32)value, -1, -1, -1)) { @@ -371,7 +423,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheM jboolean ret = JNI_FALSE; #if defined(J9VM_OPT_SHARED_CLASSES) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; if (javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)-1, -1, (I_32)value, -1, -1)) { @@ -388,7 +440,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheM jboolean ret = JNI_FALSE; #if defined(J9VM_OPT_SHARED_CLASSES) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; if (javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)-1, -1, -1, (I_32)value, -1)) { @@ -405,7 +457,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheM jboolean ret = JNI_FALSE; #if defined(J9VM_OPT_SHARED_CLASSES) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; if (javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)-1, -1, -1, -1, (I_32)value)) { @@ -422,7 +474,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getSharedClassCacheS U_32 ret = 0; #if defined(J9VM_OPT_SHARED_CLASSES) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; if (javaVM->sharedClassConfig) { javaVM->sharedClassConfig->getUnstoredBytes(javaVM, &ret, NULL, NULL); @@ -437,7 +489,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getSharedClassCacheM U_32 ret = 0; #if defined(J9VM_OPT_SHARED_CLASSES) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; if (javaVM->sharedClassConfig) { javaVM->sharedClassConfig->getUnstoredBytes(javaVM, NULL, &ret, NULL); @@ -452,7 +504,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getSharedClassCacheM U_32 ret = 0; #if defined(J9VM_OPT_SHARED_CLASSES) - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; if (javaVM->sharedClassConfig) { javaVM->sharedClassConfig->getUnstoredBytes(javaVM, NULL, NULL, &ret); @@ -470,7 +522,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_isSetMaxHeapSizeSupp jstring JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCModeImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; const char *gcMode = javaVM->memoryManagerFunctions->j9gc_get_gcmodestring(javaVM); if (NULL != gcMode) { @@ -483,7 +535,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCModeImpl(JNIEnv jlong JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCMainThreadCpuUsedImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; jlong result = 0; @@ -497,12 +549,12 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCMainThreadCpuUs jlong JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCWorkerThreadsCpuUsedImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; jlong result = 0; omrthread_rwmutex_enter_read(mgmt->managementDataLock); - result = (jlong) mgmt->gcWorkerCpuTime; + result = (jlong)mgmt->gcWorkerCpuTime; omrthread_rwmutex_exit_read(mgmt->managementDataLock); return result; @@ -511,12 +563,12 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCWorkerThreadsCp jint JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMaximumGCThreadsImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; jint result = 0; omrthread_rwmutex_enter_read(mgmt->managementDataLock); - result = (jint) mgmt->gcMaxThreads; + result = (jint)mgmt->gcMaxThreads; omrthread_rwmutex_exit_read(mgmt->managementDataLock); return result; @@ -525,12 +577,12 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMaximumGCThreadsI jint JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getCurrentGCThreadsImpl(JNIEnv *env, jobject beanInstance) { - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; jint result = 0; omrthread_rwmutex_enter_read(mgmt->managementDataLock); - result = (jint) mgmt->gcCurrentThreads; + result = (jint)mgmt->gcCurrentThreads; omrthread_rwmutex_exit_read(mgmt->managementDataLock); return result; @@ -541,7 +593,7 @@ void JNICALL Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificationLoop(JNIEnv *env, jobject threadInstance) { /* currently, the only notification queue is for the heap */ - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; jclass threadClass = NULL; jclass stringClass = NULL; @@ -726,7 +778,7 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati } else { /* dispatch usage threshold Notification */ memoryPoolUsageThreshold *usageThreshold = notification->usageThreshold; - idx = (U_32) getIndexFromMemoryPoolID(mgmt, usageThreshold->poolID); + idx = (U_32)getIndexFromMemoryPoolID(mgmt, usageThreshold->poolID); pool = &mgmt->memoryPools[idx]; poolName = poolNames[idx]; if (THRESHOLD_EXCEEDED == notification->type) { @@ -788,7 +840,7 @@ void JNICALL Java_com_ibm_lang_management_internal_MemoryNotificationThreadShutdown_sendShutdownNotification(JNIEnv *env, jobject instance) { /* currently, the only queue is the heap usage notification queue */ - J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; + J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; J9MemoryNotification *notification = NULL; J9MemoryNotification *next = NULL; diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index dafc7c6fcd6..7bda00505c9 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -3573,8 +3573,19 @@ typedef struct J9HookedNative { UDATA userdata; } J9HookedNative; -/* @ddr_namespace: map_to_type=J9ClassLoader */ +typedef struct J9RAMClassFreeLists { + struct J9RAMClassFreeListBlock *ramClassTinyBlockFreeList; + struct J9RAMClassFreeListBlock *ramClassSmallBlockFreeList; + struct J9RAMClassFreeListBlock *ramClassLargeBlockFreeList; +} J9RAMClassFreeLists; + +typedef struct J9RAMClassUDATABlockFreeList { + UDATA *ramClassSub4gUDATABlockFreeList; + UDATA *ramClassFreqUDATABlockFreeList; + UDATA *ramClassInFreqUDATABlockFreeList; +} J9RAMClassUDATABlockFreeList; +/* @ddr_namespace: map_to_type=J9ClassLoader */ typedef struct J9ClassLoader { struct J9Pool* sharedLibraries; struct J9HashTable* classHashTable; @@ -3594,10 +3605,10 @@ typedef struct J9ClassLoader { #endif /* defined(J9VM_NEEDS_JNI_REDIRECTION) */ struct J9JITExceptionTable* jitMetaDataList; struct J9MemorySegment* classSegments; - struct J9RAMClassFreeListBlock* ramClassLargeBlockFreeList; - struct J9RAMClassFreeListBlock* ramClassSmallBlockFreeList; - struct J9RAMClassFreeListBlock* ramClassTinyBlockFreeList; - UDATA* ramClassUDATABlockFreeList; + struct J9RAMClassFreeLists sub4gBlock; + struct J9RAMClassFreeLists frequentlyAccessedBlock; + struct J9RAMClassFreeLists inFrequentlyAccessedBlock; + struct J9RAMClassUDATABlockFreeList ramClassUDATABlocks; struct J9HashTable* redefinedClasses; struct J9NativeLibrary* librariesHead; struct J9NativeLibrary* librariesTail; diff --git a/runtime/vm/createramclass.cpp b/runtime/vm/createramclass.cpp index 598aa6a74b6..f444ab6d691 100644 --- a/runtime/vm/createramclass.cpp +++ b/runtime/vm/createramclass.cpp @@ -108,6 +108,12 @@ typedef struct J9RAMClassFreeListLargeBlock { UDATA maxSizeInList; } J9RAMClassFreeListLargeBlock; +enum SegmentKind { + SUB4G = 0, + FREQUENTLY_ACCESSED, + INFREQUENTLY_ACCESSED +}; + typedef struct RAMClassAllocationRequest { UDATA prefixSize; UDATA alignment; @@ -115,6 +121,7 @@ typedef struct RAMClassAllocationRequest { UDATA *address; UDATA index; UDATA fragmentSize; + SegmentKind segmentKind; struct RAMClassAllocationRequest *next; } RAMClassAllocationRequest; @@ -577,7 +584,7 @@ addInterfaceMethods(J9VMThread *vmStruct, J9ClassLoader *classLoader, J9Class *i const UDATA combinedModifiers = J9_ROM_METHOD_FROM_RAM_METHOD(interfaceMethod)->modifiers | vTableMethod->modifiers; if (J9_ARE_ANY_BITS_SET(combinedModifiers, J9AccAbstract)) { /* Convert to equivSet by adding the existing vtable method to the equivSet */ - J9EquivalentEntry *entry = (J9EquivalentEntry*) pool_newElement(equivalentSets); + J9EquivalentEntry *entry = (J9EquivalentEntry*)pool_newElement(equivalentSets); if (NULL == entry) { /* OOM will be thrown */ goto fail; @@ -610,7 +617,7 @@ addInterfaceMethods(J9VMThread *vmStruct, J9ClassLoader *classLoader, J9Class *i existing_entry = existing_entry->next; } existing_entry = previous_entry; - J9EquivalentEntry * new_entry = (J9EquivalentEntry*) pool_newElement(equivalentSets); + J9EquivalentEntry * new_entry = (J9EquivalentEntry*)pool_newElement(equivalentSets); if (NULL == new_entry) { /* OOM will be thrown */ goto fail; @@ -1497,9 +1504,9 @@ compareRomClassName(void *item, J9StackElement *currentElement) { J9UTF8 *currentRomName; BOOLEAN rc = FALSE; - J9UTF8 *className = J9ROMCLASS_CLASSNAME((J9ROMClass *) item); + J9UTF8 *className = J9ROMCLASS_CLASSNAME((J9ROMClass *)item); - currentRomName = J9ROMCLASS_CLASSNAME((J9ROMClass *) currentElement->element); + currentRomName = J9ROMCLASS_CLASSNAME((J9ROMClass *)currentElement->element); if (0 == compareUTF8Length(J9UTF8_DATA(currentRomName), J9UTF8_LENGTH(currentRomName), J9UTF8_DATA(className), J9UTF8_LENGTH(className))) { @@ -1576,7 +1583,7 @@ verifyLoadingOrLinkingStack(J9VMThread *vmThread, J9ClassLoader *classLoader, vo setNativeOutOfMemoryError(vmThread, 0, 0); return FALSE; } - newTopOfStack->element = (void *) clazz; + newTopOfStack->element = (void *)clazz; newTopOfStack->previous = *stack; newTopOfStack->classLoader = classLoader; *stack = newTopOfStack; @@ -1772,13 +1779,13 @@ loadSuperClassAndInterfaces(J9VMThread *vmThread, J9ClassLoader *classLoader, J9 for (i = 0; iinterfaceCount; i++) { J9UTF8 *interfaceName = NNSRP_GET(interfaceNames[i], J9UTF8*); - + if (J9UTF8_EQUALS(interfaceName, className)) { /* className and interfaceName are the same */ setCurrentException(vmThread, J9VMCONSTANTPOOL_JAVALANGCLASSCIRCULARITYERROR, NULL); return FALSE; } - + J9Class *interfaceClass = internalFindClassUTF8(vmThread, J9UTF8_DATA(interfaceName), J9UTF8_LENGTH(interfaceName), classLoader, classPreloadFlags); Trc_VM_CreateRAMClassFromROMClass_loadedInterface(vmThread, J9UTF8_LENGTH(interfaceName), J9UTF8_DATA(interfaceName), interfaceClass); @@ -2027,7 +2034,7 @@ loadFlattenableFieldValueClasses(J9VMThread *currentThread, J9ClassLoader *class } else { if (J9_ARE_ALL_BITS_SET(modifiers, J9FieldFlagIsNullRestricted)) { J9FlattenedClassCacheEntry *entry = J9_VM_FCC_ENTRY_FROM_FCC(flattenedClassCache, flattenableFieldCount); - entry->clazz = (J9Class *) J9_VM_FCC_CLASS_FLAGS_STATIC_FIELD; + entry->clazz = (J9Class *)J9_VM_FCC_CLASS_FLAGS_STATIC_FIELD; entry->field = field; entry->offset = UDATA_MAX; flattenableFieldCount += 1; @@ -2407,7 +2414,7 @@ internalCreateRAMClassDone(J9VMThread *vmThread, J9ClassLoader *classLoader, J9C javaVM->memoryManagerFunctions->j9gc_modron_global_collect_with_overrides(vmThread, J9MMCONSTANT_EXPLICIT_GC_NATIVE_OUT_OF_MEMORY); state->classObject = POP_OBJECT_IN_SPECIAL_FRAME(vmThread); omrthread_monitor_enter(javaVM->classTableMutex); - + if (J9_ARE_NO_BITS_SET(options, J9_FINDCLASS_FLAG_HIDDEN)) { /* If the class was successfully loaded while we were GCing, use that one */ if (elementClass == NULL) { @@ -2418,7 +2425,7 @@ internalCreateRAMClassDone(J9VMThread *vmThread, J9ClassLoader *classLoader, J9C if (alreadyLoadedClass != NULL) { goto alreadyLoaded; } - + /* Try the store again - if it fails again, throw native OOM */ if (hashClassTableAtPut(vmThread, classLoader, J9UTF8_DATA(className), J9UTF8_LENGTH(className), state->ramClass)) { goto nativeOOM; @@ -2532,7 +2539,7 @@ trcModulesSettingPackage(J9VMThread *vmThread, J9Class *ramClass, J9ClassLoader static void initializeClassLinks(J9Class *ramClass, J9Class *superclass, J9MemorySegment *segment, UDATA options) { - ramClass->nextClassInSegment = *(J9Class **) segment->heapBase; + ramClass->nextClassInSegment = *(J9Class **)segment->heapBase; *(J9Class **)segment->heapBase = ramClass; ramClass->subclassTraversalLink = ramClass; @@ -2869,9 +2876,9 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas omrthread_monitor_exit(bcvd->verifierMutex); #if JAVA_SPEC_VERSION >= 16 - setCurrentExceptionUTF(vmThread, J9VMCONSTANTPOOL_JAVALANGINCOMPATIBLECLASSCHANGEERROR, (char *) verifyErrorString); + setCurrentExceptionUTF(vmThread, J9VMCONSTANTPOOL_JAVALANGINCOMPATIBLECLASSCHANGEERROR, (char *)verifyErrorString); #else /* JAVA_SPEC_VERSION >= 16 */ - setCurrentExceptionUTF(vmThread, J9VMCONSTANTPOOL_JAVALANGVERIFYERROR, (char *) verifyErrorString); + setCurrentExceptionUTF(vmThread, J9VMCONSTANTPOOL_JAVALANGVERIFYERROR, (char *)verifyErrorString); #endif /* JAVA_SPEC_VERSION >= 16 */ j9mem_free_memory(verifyErrorString); @@ -2908,12 +2915,14 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas allocationRequests[RAM_CLASS_HEADER_FRAGMENT].alignment = J9_REQUIRED_CLASS_ALIGNMENT; allocationRequests[RAM_CLASS_HEADER_FRAGMENT].alignedSize = sizeof(J9Class) + vTableSlots * sizeof(UDATA); allocationRequests[RAM_CLASS_HEADER_FRAGMENT].address = NULL; + allocationRequests[RAM_CLASS_HEADER_FRAGMENT].segmentKind = SUB4G; /* RAM methods fragment */ allocationRequests[RAM_METHODS_FRAGMENT].prefixSize = extendedMethodBlockSize * sizeof(UDATA); allocationRequests[RAM_METHODS_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_METHODS_FRAGMENT].alignedSize = (romClass->romMethodCount + defaultConflictCount) * sizeof(J9Method); allocationRequests[RAM_METHODS_FRAGMENT].address = NULL; + allocationRequests[RAM_METHODS_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* superclasses fragment */ allocationRequests[RAM_SUPERCLASSES_FRAGMENT].prefixSize = 0; @@ -2925,36 +2934,42 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas } allocationRequests[RAM_SUPERCLASSES_FRAGMENT].alignedSize = OMR_MAX(superclassSizeBytes, minimumSuperclassArraySizeBytes); allocationRequests[RAM_SUPERCLASSES_FRAGMENT].address = NULL; + allocationRequests[RAM_SUPERCLASSES_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* instance description fragment */ allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].prefixSize = 0; allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].alignedSize = instanceDescriptionSlotCount * sizeof(UDATA); allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].address = NULL; + allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* iTable fragment */ allocationRequests[RAM_ITABLE_FRAGMENT].prefixSize = 0; allocationRequests[RAM_ITABLE_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_ITABLE_FRAGMENT].alignedSize = iTableSlotCount * sizeof(UDATA); allocationRequests[RAM_ITABLE_FRAGMENT].address = NULL; + allocationRequests[RAM_ITABLE_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* static slots fragment */ allocationRequests[RAM_STATICS_FRAGMENT].prefixSize = 0; allocationRequests[RAM_STATICS_FRAGMENT].alignment = sizeof(U_64); allocationRequests[RAM_STATICS_FRAGMENT].alignedSize = totalStaticSlots * sizeof(UDATA); allocationRequests[RAM_STATICS_FRAGMENT].address = NULL; + allocationRequests[RAM_STATICS_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* constant pool fragment */ allocationRequests[RAM_CONSTANT_POOL_FRAGMENT].prefixSize = 0; allocationRequests[RAM_CONSTANT_POOL_FRAGMENT].alignment = REQUIRED_CONSTANT_POOL_ALIGNMENT; allocationRequests[RAM_CONSTANT_POOL_FRAGMENT].alignedSize = romClass->ramConstantPoolCount * 2 * sizeof(UDATA); allocationRequests[RAM_CONSTANT_POOL_FRAGMENT].address = NULL; + allocationRequests[RAM_CONSTANT_POOL_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* call sites fragment */ allocationRequests[RAM_CALL_SITES_FRAGMENT].prefixSize = 0; allocationRequests[RAM_CALL_SITES_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_CALL_SITES_FRAGMENT].alignedSize = romClass->callSiteCount * sizeof(UDATA); allocationRequests[RAM_CALL_SITES_FRAGMENT].address = NULL; + allocationRequests[RAM_CALL_SITES_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; #if defined(J9VM_OPT_OPENJDK_METHODHANDLE) /* invoke cache fragment */ @@ -2962,17 +2977,20 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas allocationRequests[RAM_INVOKE_CACHE_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_INVOKE_CACHE_FRAGMENT].alignedSize = romClass->invokeCacheCount * sizeof(UDATA); allocationRequests[RAM_INVOKE_CACHE_FRAGMENT].address = NULL; + allocationRequests[RAM_INVOKE_CACHE_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; #else /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */ /* method types fragment */ allocationRequests[RAM_METHOD_TYPES_FRAGMENT].prefixSize = 0; allocationRequests[RAM_METHOD_TYPES_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_METHOD_TYPES_FRAGMENT].alignedSize = romClass->methodTypeCount * sizeof(UDATA); allocationRequests[RAM_METHOD_TYPES_FRAGMENT].address = NULL; + allocationRequests[RAM_METHOD_TYPES_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* varhandle method types fragment */ allocationRequests[RAM_VARHANDLE_METHOD_TYPES_FRAGMENT].prefixSize = 0; allocationRequests[RAM_VARHANDLE_METHOD_TYPES_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_VARHANDLE_METHOD_TYPES_FRAGMENT].alignedSize = romClass->varHandleMethodTypeCount * sizeof(UDATA); allocationRequests[RAM_VARHANDLE_METHOD_TYPES_FRAGMENT].address = NULL; + allocationRequests[RAM_VARHANDLE_METHOD_TYPES_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; #endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */ /* static split table fragment */ @@ -2980,12 +2998,14 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas allocationRequests[RAM_STATIC_SPLIT_TABLE_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_STATIC_SPLIT_TABLE_FRAGMENT].alignedSize = romClass->staticSplitMethodRefCount * sizeof(J9Method *); allocationRequests[RAM_STATIC_SPLIT_TABLE_FRAGMENT].address = NULL; + allocationRequests[RAM_STATIC_SPLIT_TABLE_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* special split table fragment */ allocationRequests[RAM_SPECIAL_SPLIT_TABLE_FRAGMENT].prefixSize = 0; allocationRequests[RAM_SPECIAL_SPLIT_TABLE_FRAGMENT].alignment = sizeof(UDATA); allocationRequests[RAM_SPECIAL_SPLIT_TABLE_FRAGMENT].alignedSize = romClass->specialSplitMethodRefCount * sizeof(J9Method *); allocationRequests[RAM_SPECIAL_SPLIT_TABLE_FRAGMENT].address = NULL; + allocationRequests[RAM_SPECIAL_SPLIT_TABLE_FRAGMENT].segmentKind = FREQUENTLY_ACCESSED; /* flattened classes cache */ #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) @@ -2997,17 +3017,18 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas allocationRequests[RAM_CLASS_FLATTENED_CLASS_CACHE].alignment = OMR_MAX(sizeof(J9Class *), sizeof(UDATA)); allocationRequests[RAM_CLASS_FLATTENED_CLASS_CACHE].alignedSize = flattenedClassCacheAllocSize; allocationRequests[RAM_CLASS_FLATTENED_CLASS_CACHE].address = NULL; + allocationRequests[RAM_CLASS_FLATTENED_CLASS_CACHE].segmentKind = FREQUENTLY_ACCESSED; #endif /* J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES */ if (fastHCR) { /* For shared fragments, set alignedSize and prefixSize to 0 to make internalAllocateRAMClass() ignore them. */ - allocationRequests[RAM_SUPERCLASSES_FRAGMENT].address = (UDATA *) classBeingRedefined->superclasses; + allocationRequests[RAM_SUPERCLASSES_FRAGMENT].address = (UDATA *)classBeingRedefined->superclasses; allocationRequests[RAM_SUPERCLASSES_FRAGMENT].prefixSize = 0; allocationRequests[RAM_SUPERCLASSES_FRAGMENT].alignedSize = 0; allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].address = classBeingRedefined->instanceDescription; allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].prefixSize = 0; allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].alignedSize = 0; - allocationRequests[RAM_ITABLE_FRAGMENT].address = (UDATA *) classBeingRedefined->iTable; + allocationRequests[RAM_ITABLE_FRAGMENT].address = (UDATA *)classBeingRedefined->iTable; allocationRequests[RAM_ITABLE_FRAGMENT].prefixSize = 0; allocationRequests[RAM_ITABLE_FRAGMENT].alignedSize = 0; allocationRequests[RAM_STATICS_FRAGMENT].address = classBeingRedefined->ramStatics; @@ -3017,9 +3038,9 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas segment = internalAllocateRAMClass(javaVM, classLoader, allocationRequests, RAM_CLASS_FRAGMENT_COUNT); if (NULL != segment) { - ramClass = (J9Class *) allocationRequests[RAM_CLASS_HEADER_FRAGMENT].address; + ramClass = (J9Class *)allocationRequests[RAM_CLASS_HEADER_FRAGMENT].address; state->ramClass = ramClass; - ramClass->ramMethods = (J9Method *) allocationRequests[RAM_METHODS_FRAGMENT].address; + ramClass->ramMethods = (J9Method *)allocationRequests[RAM_METHODS_FRAGMENT].address; if (fastHCR) { /* Share iTable and instanceDescription (and associated fields) with class being redefined. */ ramClass->iTable = classBeingRedefined->iTable; @@ -3035,26 +3056,26 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas instanceDescription = allocationRequests[RAM_INSTANCE_DESCRIPTION_FRAGMENT].address; iTable = allocationRequests[RAM_ITABLE_FRAGMENT].address; } - ramClass->superclasses = (J9Class **) allocationRequests[RAM_SUPERCLASSES_FRAGMENT].address; + ramClass->superclasses = (J9Class **)allocationRequests[RAM_SUPERCLASSES_FRAGMENT].address; ramClass->ramStatics = allocationRequests[RAM_STATICS_FRAGMENT].address; - ramClass->ramConstantPool = (J9ConstantPool *) allocationRequests[RAM_CONSTANT_POOL_FRAGMENT].address; - ramClass->callSites = (j9object_t *) allocationRequests[RAM_CALL_SITES_FRAGMENT].address; + ramClass->ramConstantPool = (J9ConstantPool *)allocationRequests[RAM_CONSTANT_POOL_FRAGMENT].address; + ramClass->callSites = (j9object_t *)allocationRequests[RAM_CALL_SITES_FRAGMENT].address; #if defined(J9VM_OPT_OPENJDK_METHODHANDLE) - ramClass->invokeCache = (j9object_t *) allocationRequests[RAM_INVOKE_CACHE_FRAGMENT].address; + ramClass->invokeCache = (j9object_t *)allocationRequests[RAM_INVOKE_CACHE_FRAGMENT].address; #else /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */ - ramClass->methodTypes = (j9object_t *) allocationRequests[RAM_METHOD_TYPES_FRAGMENT].address; - ramClass->varHandleMethodTypes = (j9object_t *) allocationRequests[RAM_VARHANDLE_METHOD_TYPES_FRAGMENT].address; + ramClass->methodTypes = (j9object_t *)allocationRequests[RAM_METHOD_TYPES_FRAGMENT].address; + ramClass->varHandleMethodTypes = (j9object_t *)allocationRequests[RAM_VARHANDLE_METHOD_TYPES_FRAGMENT].address; #endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */ - ramClass->staticSplitMethodTable = (J9Method **) allocationRequests[RAM_STATIC_SPLIT_TABLE_FRAGMENT].address; + ramClass->staticSplitMethodTable = (J9Method **)allocationRequests[RAM_STATIC_SPLIT_TABLE_FRAGMENT].address; for (U_16 i = 0; i < romClass->staticSplitMethodRefCount; ++i) { ramClass->staticSplitMethodTable[i] = (J9Method*)javaVM->initialMethods.initialStaticMethod; } - ramClass->specialSplitMethodTable = (J9Method **) allocationRequests[RAM_SPECIAL_SPLIT_TABLE_FRAGMENT].address; + ramClass->specialSplitMethodTable = (J9Method **)allocationRequests[RAM_SPECIAL_SPLIT_TABLE_FRAGMENT].address; for (U_16 i = 0; i < romClass->specialSplitMethodRefCount; ++i) { ramClass->specialSplitMethodTable[i] = (J9Method*)javaVM->initialMethods.initialSpecialMethod; } #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) - ramClass->flattenedClassCache = (J9FlattenedClassCache *) allocationRequests[RAM_CLASS_FLATTENED_CLASS_CACHE].address; + ramClass->flattenedClassCache = (J9FlattenedClassCache *)allocationRequests[RAM_CLASS_FLATTENED_CLASS_CACHE].address; if (0 != flattenedClassCacheAllocSize) { memcpy(ramClass->flattenedClassCache, flattenedClassCache, flattenedClassCacheAllocSize); } @@ -3321,7 +3342,7 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas initializeRAMClassITable(vmThread, ramClass, superclass, iTable, interfaceHead, maxInterfaceDepth); } /* Ensure that lastITable is never NULL */ - ramClass->lastITable = (J9ITable *) ramClass->iTable; + ramClass->lastITable = (J9ITable *)ramClass->iTable; if (NULL == ramClass->lastITable) { ramClass->lastITable = (J9ITable *) &invalidITable; } @@ -3543,7 +3564,7 @@ internalCreateRAMClassFromROMClass(J9VMThread *vmThread, J9ClassLoader *classLoa UDATA valueTypeFlags = 0; UDATA flattenedClassCacheAllocSize = sizeof(J9FlattenedClassCache) + (sizeof(J9FlattenedClassCacheEntry) * romFieldCount); U_8 flattenedClassCacheBuffer[sizeof(J9FlattenedClassCache) + (sizeof(J9FlattenedClassCacheEntry) * DEFAULT_NUMBER_OF_ENTRIES_IN_FLATTENED_CLASS_CACHE)] = {0}; - J9FlattenedClassCache *flattenedClassCache = (J9FlattenedClassCache *) flattenedClassCacheBuffer; + J9FlattenedClassCache *flattenedClassCache = (J9FlattenedClassCache *)flattenedClassCacheBuffer; PORT_ACCESS_FROM_VMC(vmThread); #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ @@ -3673,7 +3694,7 @@ internalCreateRAMClassFromROMClass(J9VMThread *vmThread, J9ClassLoader *classLoa } #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) if (romFieldCount > DEFAULT_NUMBER_OF_ENTRIES_IN_FLATTENED_CLASS_CACHE) { - flattenedClassCache = (J9FlattenedClassCache *) j9mem_allocate_memory(flattenedClassCacheAllocSize, J9MEM_CATEGORY_CLASSES); + flattenedClassCache = (J9FlattenedClassCache *)j9mem_allocate_memory(flattenedClassCacheAllocSize, J9MEM_CATEGORY_CLASSES); if (NULL == flattenedClassCache) { setNativeOutOfMemoryError(vmThread, 0, 0); omrthread_monitor_enter(javaVM->classTableMutex); @@ -3703,7 +3724,7 @@ internalCreateRAMClassFromROMClass(J9VMThread *vmThread, J9ClassLoader *classLoa result = internalCreateRAMClassFromROMClassImpl(vmThread, classLoader, romClass, options, elementClass, methodRemapArray, entryIndex, locationType, classBeingRedefined, superclass, &state, hostClassLoader, hostClass, module, flattenedClassCache, &valueTypeFlags); - if (flattenedClassCache != (J9FlattenedClassCache *) flattenedClassCacheBuffer) { + if (flattenedClassCache != (J9FlattenedClassCache *)flattenedClassCacheBuffer) { j9mem_free_memory(flattenedClassCache); } #else @@ -3722,12 +3743,12 @@ internalCreateRAMClassFromROMClass(J9VMThread *vmThread, J9ClassLoader *classLoa } static VMINLINE void -addBlockToLargeFreeList(J9ClassLoader *classLoader, J9RAMClassFreeListLargeBlock *block) +addBlockToLargeFreeList(J9ClassLoader *classLoader, J9RAMClassFreeListLargeBlock *block, J9RAMClassFreeLists *blockFreeLists) { - J9RAMClassFreeListLargeBlock *tailBlock = (J9RAMClassFreeListLargeBlock *) classLoader->ramClassLargeBlockFreeList; + J9RAMClassFreeListLargeBlock *tailBlock = (J9RAMClassFreeListLargeBlock *)blockFreeLists->ramClassLargeBlockFreeList; block->nextFreeListBlock = tailBlock; - classLoader->ramClassLargeBlockFreeList = (J9RAMClassFreeListBlock *) block; + blockFreeLists->ramClassLargeBlockFreeList = (J9RAMClassFreeListBlock *)block; if ((NULL != tailBlock) && (tailBlock->maxSizeInList > block->size)) { block->maxSizeInList = tailBlock->maxSizeInList; @@ -3737,7 +3758,7 @@ addBlockToLargeFreeList(J9ClassLoader *classLoader, J9RAMClassFreeListLargeBlock } static void -addBlockToFreeList(J9ClassLoader *classLoader, UDATA address, UDATA size) +addBlockToFreeList(J9ClassLoader *classLoader, UDATA address, UDATA size, J9RAMClassFreeLists *blockFreeLists, UDATA *ramClassUDATABlockFreelist) { if (J9_ARE_ANY_BITS_SET(classLoader->flags, J9CLASSLOADER_ANON_CLASS_LOADER)) { /* We support individual class unloading for anonymous classes, so each anonymous class @@ -3746,20 +3767,20 @@ addBlockToFreeList(J9ClassLoader *classLoader, UDATA address, UDATA size) return; } if (sizeof(UDATA) == size) { - UDATA *block = (UDATA *) address; - *block = (UDATA) classLoader->ramClassUDATABlockFreeList; - classLoader->ramClassUDATABlockFreeList = block; + UDATA *block = (UDATA *)address; + *block = (UDATA)ramClassUDATABlockFreelist; + ramClassUDATABlockFreelist = block; } else if (sizeof(J9RAMClassFreeListBlock) <= size) { - J9RAMClassFreeListBlock *block = (J9RAMClassFreeListBlock *) address; + J9RAMClassFreeListBlock *block = (J9RAMClassFreeListBlock *)address; block->size = size; if (RAM_CLASS_SMALL_FRAGMENT_LIMIT > size) { - block->nextFreeListBlock = classLoader->ramClassTinyBlockFreeList; - classLoader->ramClassTinyBlockFreeList = block; + block->nextFreeListBlock = blockFreeLists->ramClassTinyBlockFreeList; + blockFreeLists->ramClassTinyBlockFreeList = block; } else if (RAM_CLASS_FRAGMENT_LIMIT > size) { - block->nextFreeListBlock = classLoader->ramClassSmallBlockFreeList; - classLoader->ramClassSmallBlockFreeList = block; + block->nextFreeListBlock = blockFreeLists->ramClassSmallBlockFreeList; + blockFreeLists->ramClassSmallBlockFreeList = block; } else { - addBlockToLargeFreeList(classLoader, (J9RAMClassFreeListLargeBlock *) block); + addBlockToLargeFreeList(classLoader, (J9RAMClassFreeListLargeBlock *)block, blockFreeLists); } } } @@ -3770,19 +3791,19 @@ addBlockToFreeList(J9ClassLoader *classLoader, UDATA address, UDATA size) * list to update their maxSizeInList values. */ static void -removeBlockFromLargeFreeList(J9ClassLoader *classLoader, J9RAMClassFreeListLargeBlock **freeListBlockPtr, J9RAMClassFreeListLargeBlock *freeListBlock) +removeBlockFromLargeFreeList(J9ClassLoader *classLoader, J9RAMClassFreeListLargeBlock **freeListBlockPtr, J9RAMClassFreeListLargeBlock *freeListBlock, J9RAMClassFreeLists *blockFreeLists) { J9RAMClassFreeListLargeBlock *nextBlock = freeListBlock->nextFreeListBlock; if ((NULL == nextBlock) || (freeListBlock->maxSizeInList != nextBlock->maxSizeInList)) { /* Re-compute the maxSizeInList values on earlier blocks by re-adding them to the list. */ - J9RAMClassFreeListLargeBlock *block = (J9RAMClassFreeListLargeBlock *) classLoader->ramClassLargeBlockFreeList; + J9RAMClassFreeListLargeBlock *block = (J9RAMClassFreeListLargeBlock *)blockFreeLists->ramClassLargeBlockFreeList; - classLoader->ramClassLargeBlockFreeList = (J9RAMClassFreeListBlock *) freeListBlock->nextFreeListBlock; + blockFreeLists->ramClassLargeBlockFreeList = (J9RAMClassFreeListBlock *)freeListBlock->nextFreeListBlock; while (block != freeListBlock) { J9RAMClassFreeListLargeBlock *nextBlock = block->nextFreeListBlock; - addBlockToLargeFreeList(classLoader, block); + addBlockToLargeFreeList(classLoader, block, blockFreeLists); block = nextBlock; } } else { @@ -3800,11 +3821,11 @@ removeBlockFromLargeFreeList(J9ClassLoader *classLoader, J9RAMClassFreeListLarge * Returns TRUE if the fragment was allocated. */ static BOOLEAN -allocateRAMClassFragmentFromFreeList(RAMClassAllocationRequest *request, J9RAMClassFreeListBlock **freeList, J9ClassLoader *classLoader) +allocateRAMClassFragmentFromFreeList(RAMClassAllocationRequest *request, J9RAMClassFreeListBlock **freeList, J9ClassLoader *classLoader, UDATA *ramClassUDATABlockFreelist, J9RAMClassFreeLists *blockFreeLists) { J9RAMClassFreeListBlock **freeListBlockPtr = freeList; J9RAMClassFreeListBlock *freeListBlock = *freeListBlockPtr; - const BOOLEAN islargeBlocksList = (freeList == &classLoader->ramClassLargeBlockFreeList); + const BOOLEAN islargeBlocksList = (freeList == &blockFreeLists->ramClassLargeBlockFreeList); const UDATA alignmentMask = (request->alignment == sizeof(UDATA)) ? 0 : (request->alignment - 1); const UDATA prefixSize = request->prefixSize; const UDATA fragmentSize = request->fragmentSize; @@ -3812,7 +3833,7 @@ allocateRAMClassFragmentFromFreeList(RAMClassAllocationRequest *request, J9RAMCl if (islargeBlocksList) { /* Fail fast if the requested size is larger than anything in the free list. */ - if (fragmentSize + alignmentMask > ((J9RAMClassFreeListLargeBlock *) freeListBlock)->maxSizeInList) { + if (fragmentSize + alignmentMask > ((J9RAMClassFreeListLargeBlock *)freeListBlock)->maxSizeInList) { return FALSE; } } @@ -3821,7 +3842,7 @@ allocateRAMClassFragmentFromFreeList(RAMClassAllocationRequest *request, J9RAMCl while (NULL != freeListBlock) { /* Allocate from the start of the block */ - UDATA addressForAlignedArea = ((UDATA) freeListBlock) + prefixSize; + UDATA addressForAlignedArea = ((UDATA)freeListBlock) + prefixSize; UDATA alignmentMod = addressForAlignedArea & alignmentMask; UDATA alignmentShift = (0 == alignmentMod) ? 0 : (alignment - alignmentMod); @@ -3833,7 +3854,7 @@ allocateRAMClassFragmentFromFreeList(RAMClassAllocationRequest *request, J9RAMCl Trc_VM_internalAllocateRAMClass_AllocatedFromFreeList(request->index, freeListBlock, freeListBlock->size, request->address, request->prefixSize, request->alignedSize, request->alignment); if (islargeBlocksList) { - removeBlockFromLargeFreeList(classLoader, (J9RAMClassFreeListLargeBlock **) freeListBlockPtr, (J9RAMClassFreeListLargeBlock *) freeListBlock); + removeBlockFromLargeFreeList(classLoader, (J9RAMClassFreeListLargeBlock **)freeListBlockPtr, (J9RAMClassFreeListLargeBlock *)freeListBlock, blockFreeLists); } else { *freeListBlockPtr = freeListBlock->nextFreeListBlock; freeListBlock->nextFreeListBlock = NULL; @@ -3841,12 +3862,12 @@ allocateRAMClassFragmentFromFreeList(RAMClassAllocationRequest *request, J9RAMCl /* Add a new block with the remaining space at the start of this block, if any, to an appropriate free list */ if (0 != alignmentShift) { - addBlockToFreeList(classLoader, (UDATA) freeListBlock, alignmentShift); + addBlockToFreeList(classLoader, (UDATA)freeListBlock, alignmentShift, blockFreeLists, ramClassUDATABlockFreelist); } /* Add a new block with the remaining space at the end of this block, if any, to an appropriate free list */ if (0 != newBlockSize) { - addBlockToFreeList(classLoader, ((UDATA) freeListBlock) + alignmentShift + request->fragmentSize, newBlockSize); + addBlockToFreeList(classLoader, ((UDATA)freeListBlock) + alignmentShift + request->fragmentSize, newBlockSize, blockFreeLists, ramClassUDATABlockFreelist); } return TRUE; @@ -3860,6 +3881,251 @@ allocateRAMClassFragmentFromFreeList(RAMClassAllocationRequest *request, J9RAMCl return FALSE; } +/** + * Allocates fragments from free list. + */ +static void +allocateFreeListBlock (RAMClassAllocationRequest *request, J9ClassLoader *classLoader, RAMClassAllocationRequest *prev, J9RAMClassFreeLists *blockFreeLists, UDATA *ramClassUDATABlockFreelist) +{ + if ((sizeof(UDATA) == request->fragmentSize) + && (NULL != ramClassUDATABlockFreelist) + ) { + UDATA *block = ramClassUDATABlockFreelist; + if (sizeof(UDATA) == request->alignment) { + request->address = ramClassUDATABlockFreelist; + ramClassUDATABlockFreelist = *(UDATA **)ramClassUDATABlockFreelist; + } else { + UDATA **blockPtr = &ramClassUDATABlockFreelist; + while (NULL != block) { + /* Check alignment constraint */ + if (0 == (((UDATA)block) & (request->alignment - 1))) { + /* Unhook block from list */ + *blockPtr = *(UDATA **)block; + *block = (UDATA)NULL; + + /* Record allocation & adjust for alignment */ + request->address = block; + break; + } + + /* Advance to next block */ + blockPtr = *(UDATA ***)block; + block = *blockPtr; + } + } + if (NULL != request->address) { + if (request->prefixSize != 0) { + request->address++; + } + Trc_VM_internalAllocateRAMClass_AllocatedFromFreeList(request->index, block, sizeof(UDATA), request->address, request->prefixSize, request->alignedSize, request->alignment); + prev->next = request->next; + return; + } + } + + if ((RAM_CLASS_SMALL_FRAGMENT_LIMIT > request->fragmentSize) + && (NULL != blockFreeLists->ramClassTinyBlockFreeList) + ) { + if (allocateRAMClassFragmentFromFreeList(request, &blockFreeLists->ramClassTinyBlockFreeList, classLoader, ramClassUDATABlockFreelist, blockFreeLists)) { + prev->next = request->next; + return; + } + } + /* Avoid scanning the small free block list to allocate RAM class headers. The alignment constraint will rarely be satisfied. */ + if ((RAM_CLASS_FRAGMENT_LIMIT > request->fragmentSize + request->alignment) + && (NULL != blockFreeLists->ramClassSmallBlockFreeList) + ) { + if (allocateRAMClassFragmentFromFreeList(request, &blockFreeLists->ramClassSmallBlockFreeList, classLoader, ramClassUDATABlockFreelist, blockFreeLists)) { + prev->next = request->next; + return; + } + } + if (NULL != blockFreeLists->ramClassLargeBlockFreeList) { + if (allocateRAMClassFragmentFromFreeList(request, &blockFreeLists->ramClassLargeBlockFreeList, classLoader, ramClassUDATABlockFreelist, blockFreeLists)) { + prev->next = request->next; + return; + } + } +} + + +static BOOLEAN +allocateRemainingFragments(RAMClassAllocationRequest *requests, UDATA allocationRequestCount, J9JavaVM *javaVM, J9ClassLoader *classLoader, RAMClassAllocationRequest *allocationRequests) +{ + if (NULL != requests) { + /* Calculate required space in new segment, including maximum alignment padding */ + UDATA newSub4gSegmentSize = 0; + UDATA newFreqAccessedSegmentSize = 0; + UDATA newInFreqAccessedSegmentSize = 0; + J9MemorySegment *newSub4gSegment = NULL; + J9MemorySegment *newFreAccessedSegment = NULL; + J9MemorySegment *newInFreqAccessedSegment = NULL; + UDATA sub4gAllocAddress = 0; + UDATA freqAccessedAllocAddress = 0; + UDATA inFreqAccessedAllocAddress = 0; + UDATA sub4gFragmentsLeftToAllocate = 0; + UDATA freqAccessedFragmentsLeftToAllocate = 0; + UDATA inFreqAccessedFragmentsLeftToAllocate = 0; + RAMClassAllocationRequest *request = NULL; + BOOLEAN isNotLoadedByAnonClassLoader = classLoader != javaVM->anonClassLoader; + UDATA i = 0; + + for (request = requests; NULL != request; request = request->next) { + if(SUB4G == request->segmentKind) { + sub4gFragmentsLeftToAllocate++; + newSub4gSegmentSize += request->fragmentSize + request->alignment; + } else if (FREQUENTLY_ACCESSED == request->segmentKind) { + freqAccessedFragmentsLeftToAllocate++; + newFreqAccessedSegmentSize += request->fragmentSize + request->alignment; + } else if (INFREQUENTLY_ACCESSED == request->segmentKind) { + inFreqAccessedFragmentsLeftToAllocate++; + newInFreqAccessedSegmentSize += request->fragmentSize + request->alignment;} + } + + /* Add sizeof(UDATA) to hold the "lastAllocatedClass" pointer - only for sub4g*/ + newSub4gSegmentSize += sizeof(UDATA); + + /* Allocate a new segment of the required size */ + + UDATA classAllocationIncrement = javaVM->ramClassAllocationIncrement; + if (!isNotLoadedByAnonClassLoader) { + classAllocationIncrement = 0; + } + + Trc_VM_internalAllocateRAMClass_AllocateClassMemorySegment(sub4gFragmentsLeftToAllocate, newSub4gSegmentSize, classAllocationIncrement); + Trc_VM_internalAllocateRAMClass_AllocateClassMemorySegment(freqAccessedFragmentsLeftToAllocate, newFreqAccessedSegmentSize, classAllocationIncrement); + Trc_VM_internalAllocateRAMClass_AllocateClassMemorySegment(inFreqAccessedFragmentsLeftToAllocate, newInFreqAccessedSegmentSize, classAllocationIncrement); + + newSub4gSegment = allocateClassMemorySegment(javaVM, newSub4gSegmentSize, MEMORY_TYPE_RAM_CLASS, classLoader, classAllocationIncrement); + newFreAccessedSegment = allocateClassMemorySegment(javaVM, newFreqAccessedSegmentSize, MEMORY_TYPE_RAM_CLASS, classLoader, classAllocationIncrement); + newInFreqAccessedSegment = allocateClassMemorySegment(javaVM, newInFreqAccessedSegmentSize, MEMORY_TYPE_RAM_CLASS, classLoader, classAllocationIncrement); + + if (NULL == newSub4gSegment) { + /* Free allocated fragments */ + /* TODO attempt to coalesce free blocks? */ + for (i = 0; i < allocationRequestCount; i++) { + if ((NULL != allocationRequests[i].address) + && (SUB4G == allocationRequests[i].segmentKind)) + { + UDATA fragmentAddress = ((UDATA)allocationRequests[i].address) - allocationRequests[i].prefixSize; + addBlockToFreeList(classLoader, fragmentAddress, allocationRequests[i].fragmentSize, &classLoader->sub4gBlock, classLoader->ramClassUDATABlocks.ramClassSub4gUDATABlockFreeList); + allocationRequests[i].address = NULL; + } + } + Trc_VM_internalAllocateRAMClass_SegmentAllocationFailed(); + return false; + } + Trc_VM_internalAllocateRAMClass_AllocatedClassMemorySegment(newSub4gSegment, newSub4gSegment->size, newSub4gSegment->heapBase, newSub4gSegment->heapTop); + + if (NULL == newFreAccessedSegment) { + /* Free allocated fragments */ + /* TODO attempt to coalesce free blocks? */ + for (i = 0; i < allocationRequestCount; i++) { + if ((NULL != allocationRequests[i].address) + && (FREQUENTLY_ACCESSED == allocationRequests[i].segmentKind)) + { + UDATA fragmentAddress = ((UDATA)allocationRequests[i].address) - allocationRequests[i].prefixSize; + addBlockToFreeList(classLoader, fragmentAddress, allocationRequests[i].fragmentSize, &classLoader->frequentlyAccessedBlock, classLoader->ramClassUDATABlocks.ramClassFreqUDATABlockFreeList); + allocationRequests[i].address = NULL; + } + } + Trc_VM_internalAllocateRAMClass_SegmentAllocationFailed(); + return false; + } + Trc_VM_internalAllocateRAMClass_AllocatedClassMemorySegment(newFreAccessedSegment, newFreAccessedSegment->size, newFreAccessedSegment->heapBase, newFreAccessedSegment->heapTop); + + if (NULL == newInFreqAccessedSegment) { + /* Free allocated fragments */ + /* TODO attempt to coalesce free blocks? */ + for (i = 0; i < allocationRequestCount; i++) { + if ((NULL != allocationRequests[i].address) + && (INFREQUENTLY_ACCESSED == allocationRequests[i].segmentKind)) + { + UDATA fragmentAddress = ((UDATA)allocationRequests[i].address) - allocationRequests[i].prefixSize; + addBlockToFreeList(classLoader, fragmentAddress, allocationRequests[i].fragmentSize, &classLoader->inFrequentlyAccessedBlock, classLoader->ramClassUDATABlocks.ramClassInFreqUDATABlockFreeList); + allocationRequests[i].address = NULL; + } + } + Trc_VM_internalAllocateRAMClass_SegmentAllocationFailed(); + return false; + } + Trc_VM_internalAllocateRAMClass_AllocatedClassMemorySegment(newInFreqAccessedSegment, newInFreqAccessedSegment->size, newInFreqAccessedSegment->heapBase, newInFreqAccessedSegment->heapTop); + + /* Initialize the "lastAllocatedClass" pointer - only for sub4g*/ + *(J9Class **)newSub4gSegment->heapBase = NULL; + + /* Bump the heapAlloc pointer to the end - don't use it again */ + newSub4gSegment->heapAlloc = newSub4gSegment->heapTop; + newFreAccessedSegment->heapAlloc = newFreAccessedSegment->heapTop; + newInFreqAccessedSegment->heapAlloc = newInFreqAccessedSegment->heapTop; + + /* Allocate the remaining fragments in the new segment, adding holes to the free list */ + sub4gAllocAddress = ((UDATA)newSub4gSegment->heapBase) + sizeof(UDATA); + freqAccessedAllocAddress = ((UDATA)newFreAccessedSegment->heapBase) + sizeof(UDATA); + inFreqAccessedAllocAddress = ((UDATA)newInFreqAccessedSegment->heapBase) + sizeof(UDATA); + for (request = requests; NULL != request; request = request->next) { + /* Allocate from the start of the segment */ + UDATA addressForAlignedArea = 0; + UDATA alignmentMod = 0; + UDATA alignmentShift = 0; + + request->address = (UDATA *) (addressForAlignedArea + alignmentShift); + if(SUB4G == request->segmentKind) { + addressForAlignedArea = sub4gAllocAddress + request->prefixSize; + alignmentMod = addressForAlignedArea & (request->alignment - 1); + alignmentShift = (0 == alignmentMod) ? 0 : (request->alignment - alignmentMod); + Trc_VM_internalAllocateRAMClass_AllocatedFromNewSegment(request->index, newSub4gSegment, request->address, request->prefixSize, request->alignedSize, request->alignment); + + /* Add a new block with the remaining space at the start of this block, if any, to an appropriate free list */ + if (0 != alignmentShift) { + addBlockToFreeList(classLoader, (UDATA)sub4gAllocAddress, alignmentShift, &classLoader->sub4gBlock, classLoader->ramClassUDATABlocks.ramClassSub4gUDATABlockFreeList); + } + sub4gAllocAddress += alignmentShift + request->fragmentSize; + sub4gFragmentsLeftToAllocate--; + + } else if (FREQUENTLY_ACCESSED == request->segmentKind) { + addressForAlignedArea = freqAccessedAllocAddress + request->prefixSize; + alignmentMod = addressForAlignedArea & (request->alignment - 1); + alignmentShift = (0 == alignmentMod) ? 0 : (request->alignment - alignmentMod); + Trc_VM_internalAllocateRAMClass_AllocatedFromNewSegment(request->index, newFreAccessedSegment, request->address, request->prefixSize, request->alignedSize, request->alignment); + + /* Add a new block with the remaining space at the start of this block, if any, to an appropriate free list */ + if (0 != alignmentShift) { + addBlockToFreeList(classLoader, (UDATA)freqAccessedAllocAddress, alignmentShift, &classLoader->frequentlyAccessedBlock, classLoader->ramClassUDATABlocks.ramClassFreqUDATABlockFreeList); + } + freqAccessedAllocAddress += alignmentShift + request->fragmentSize; + freqAccessedFragmentsLeftToAllocate--; + + } else if (INFREQUENTLY_ACCESSED == request->segmentKind) { + addressForAlignedArea = inFreqAccessedAllocAddress + request->prefixSize; + alignmentMod = addressForAlignedArea & (request->alignment - 1); + alignmentShift = (0 == alignmentMod) ? 0 : (request->alignment - alignmentMod); + Trc_VM_internalAllocateRAMClass_AllocatedFromNewSegment(request->index, newInFreqAccessedSegment, request->address, request->prefixSize, request->alignedSize, request->alignment); + + /* Add a new block with the remaining space at the start of this block, if any, to an appropriate free list */ + if (0 != alignmentShift) { + addBlockToFreeList(classLoader, (UDATA)inFreqAccessedAllocAddress, alignmentShift, &classLoader->inFrequentlyAccessedBlock, classLoader->ramClassUDATABlocks.ramClassInFreqUDATABlockFreeList); + } + inFreqAccessedAllocAddress += alignmentShift + request->fragmentSize; + inFreqAccessedFragmentsLeftToAllocate--; + } + } + + /* Add a new block with the remaining space at the end of the segment, if any, to an appropriate free list */ + if (sub4gAllocAddress != (UDATA)newSub4gSegment->heapTop) { + addBlockToFreeList(classLoader, (UDATA)sub4gAllocAddress, ((UDATA)newSub4gSegment->heapTop) - sub4gAllocAddress, &classLoader->sub4gBlock, classLoader->ramClassUDATABlocks.ramClassSub4gUDATABlockFreeList); + } + if (freqAccessedAllocAddress != (UDATA)newFreAccessedSegment->heapTop) { + addBlockToFreeList(classLoader, (UDATA)freqAccessedAllocAddress, ((UDATA)newFreAccessedSegment->heapTop) - freqAccessedAllocAddress, &classLoader->frequentlyAccessedBlock, classLoader->ramClassUDATABlocks.ramClassFreqUDATABlockFreeList); + } + if (inFreqAccessedAllocAddress != (UDATA)newInFreqAccessedSegment->heapTop) { + addBlockToFreeList(classLoader, (UDATA)inFreqAccessedAllocAddress, ((UDATA)newInFreqAccessedSegment->heapTop) - inFreqAccessedAllocAddress, &classLoader->inFrequentlyAccessedBlock, classLoader->ramClassUDATABlocks.ramClassInFreqUDATABlockFreeList); + } + } + return true; + +} + /** * Allocates fragments for a RAM class. * @@ -3875,6 +4141,7 @@ internalAllocateRAMClass(J9JavaVM *javaVM, J9ClassLoader *classLoader, RAMClassA RAMClassAllocationRequest *request = NULL; RAMClassAllocationRequest *prev = NULL; RAMClassAllocationRequest dummyHead; + BOOLEAN memoryAllocationSuccess = false; BOOLEAN isNotLoadedByAnonClassLoader = classLoader != javaVM->anonClassLoader; /* Initialize results of allocation requests and ensure sizes are at least UDATA-aligned */ @@ -3922,57 +4189,12 @@ internalAllocateRAMClass(J9JavaVM *javaVM, J9ClassLoader *classLoader, RAMClassA dummyHead.next = requests; prev = &dummyHead; for (request = requests; NULL != request; request = request->next) { - if ((sizeof(UDATA) == request->fragmentSize) && (NULL != classLoader->ramClassUDATABlockFreeList)) { - UDATA *block = classLoader->ramClassUDATABlockFreeList; - if (sizeof(UDATA) == request->alignment) { - request->address = classLoader->ramClassUDATABlockFreeList; - classLoader->ramClassUDATABlockFreeList = *(UDATA **) classLoader->ramClassUDATABlockFreeList; - } else { - UDATA **blockPtr = &classLoader->ramClassUDATABlockFreeList; - while (NULL != block) { - /* Check alignment constraint */ - if (0 == (((UDATA) block) & (request->alignment - 1))) { - /* Unhook block from list */ - *blockPtr = *(UDATA **) block; - *block = (UDATA) NULL; - - /* Record allocation & adjust for alignment */ - request->address = block; - break; - } - - /* Advance to next block */ - blockPtr = *(UDATA ***) block; - block = *blockPtr; - } - } - if (NULL != request->address) { - if (request->prefixSize != 0) { - request->address++; - } - Trc_VM_internalAllocateRAMClass_AllocatedFromFreeList(request->index, block, sizeof(UDATA), request->address, request->prefixSize, request->alignedSize, request->alignment); - prev->next = request->next; - continue; - } - } - if ((RAM_CLASS_SMALL_FRAGMENT_LIMIT > request->fragmentSize) && (NULL != classLoader->ramClassTinyBlockFreeList)) { - if (allocateRAMClassFragmentFromFreeList(request, &classLoader->ramClassTinyBlockFreeList, classLoader)) { - prev->next = request->next; - continue; - } - } - /* Avoid scanning the small free block list to allocate RAM class headers. The alignment constraint will rarely be satisfied. */ - if ((RAM_CLASS_FRAGMENT_LIMIT > request->fragmentSize + request->alignment) && (NULL != classLoader->ramClassSmallBlockFreeList)) { - if (allocateRAMClassFragmentFromFreeList(request, &classLoader->ramClassSmallBlockFreeList, classLoader)) { - prev->next = request->next; - continue; - } - } - if (NULL != classLoader->ramClassLargeBlockFreeList) { - if (allocateRAMClassFragmentFromFreeList(request, &classLoader->ramClassLargeBlockFreeList, classLoader)) { - prev->next = request->next; - continue; - } + if(SUB4G == request->segmentKind) { + allocateFreeListBlock (request, classLoader, prev, &classLoader->sub4gBlock, classLoader->ramClassUDATABlocks.ramClassSub4gUDATABlockFreeList); + } else if (FREQUENTLY_ACCESSED == request->segmentKind) { + allocateFreeListBlock (request, classLoader, prev, &classLoader->frequentlyAccessedBlock, classLoader->ramClassUDATABlocks.ramClassFreqUDATABlockFreeList); + } else if (INFREQUENTLY_ACCESSED == request->segmentKind) { + allocateFreeListBlock (request, classLoader, prev, &classLoader->inFrequentlyAccessedBlock, classLoader->ramClassUDATABlocks.ramClassInFreqUDATABlockFreeList); } prev = request; } @@ -3980,84 +4202,17 @@ internalAllocateRAMClass(J9JavaVM *javaVM, J9ClassLoader *classLoader, RAMClassA } /* If any fragments remain unallocated, allocate a new segment to (at least) fit them */ - if (NULL != requests) { - /* Calculate required space in new segment, including maximum alignment padding */ - UDATA newSegmentSize = 0; - J9MemorySegment *newSegment = NULL; - UDATA allocAddress = 0; + memoryAllocationSuccess = allocateRemainingFragments(requests, allocationRequestCount, javaVM, classLoader, allocationRequests); - fragmentsLeftToAllocate = 0; - for (request = requests; NULL != request; request = request->next) { - fragmentsLeftToAllocate++; - newSegmentSize += request->fragmentSize + request->alignment; - } - - /* Add sizeof(UDATA) to hold the "lastAllocatedClass" pointer */ - newSegmentSize += sizeof(UDATA); - - /* Allocate a new segment of the required size */ - - UDATA classAllocationIncrement = javaVM->ramClassAllocationIncrement; - if (!isNotLoadedByAnonClassLoader) { - classAllocationIncrement = 0; - } - - Trc_VM_internalAllocateRAMClass_AllocateClassMemorySegment(fragmentsLeftToAllocate, newSegmentSize, classAllocationIncrement); - newSegment = allocateClassMemorySegment(javaVM, newSegmentSize, MEMORY_TYPE_RAM_CLASS, classLoader, classAllocationIncrement); - - if (NULL == newSegment) { - /* Free allocated fragments */ - /* TODO attempt to coalesce free blocks? */ - for (i = 0; i < allocationRequestCount; i++) { - if (NULL != allocationRequests[i].address) { - UDATA fragmentAddress = ((UDATA) allocationRequests[i].address) - allocationRequests[i].prefixSize; - addBlockToFreeList(classLoader, fragmentAddress, allocationRequests[i].fragmentSize); - allocationRequests[i].address = NULL; - } - } - Trc_VM_internalAllocateRAMClass_SegmentAllocationFailed(); - return NULL; - } - Trc_VM_internalAllocateRAMClass_AllocatedClassMemorySegment(newSegment, newSegment->size, newSegment->heapBase, newSegment->heapTop); - - /* Initialize the "lastAllocatedClass" pointer */ - *(J9Class **) newSegment->heapBase = NULL; - - /* Bump the heapAlloc pointer to the end - don't use it again */ - newSegment->heapAlloc = newSegment->heapTop; - - /* Allocate the remaining fragments in the new segment, adding holes to the free list */ - allocAddress = ((UDATA) newSegment->heapBase) + sizeof(UDATA); - for (request = requests; NULL != request; request = request->next) { - /* Allocate from the start of the segment */ - UDATA addressForAlignedArea = allocAddress + request->prefixSize; - UDATA alignmentMod = addressForAlignedArea & (request->alignment - 1); - UDATA alignmentShift = (0 == alignmentMod) ? 0 : (request->alignment - alignmentMod); - - request->address = (UDATA *) (addressForAlignedArea + alignmentShift); - - Trc_VM_internalAllocateRAMClass_AllocatedFromNewSegment(request->index, newSegment, request->address, request->prefixSize, request->alignedSize, request->alignment); - - /* Add a new block with the remaining space at the start of this block, if any, to an appropriate free list */ - if (0 != alignmentShift) { - addBlockToFreeList(classLoader, (UDATA) allocAddress, alignmentShift); - } - - allocAddress += alignmentShift + request->fragmentSize; - - fragmentsLeftToAllocate--; - } - - /* Add a new block with the remaining space at the end of this segment, if any, to an appropriate free list */ - if (allocAddress != (UDATA) newSegment->heapTop) { - addBlockToFreeList(classLoader, allocAddress, ((UDATA) newSegment->heapTop) - allocAddress); - } + if(!memoryAllocationSuccess) + { + return NULL; } /* Clear all allocated fragments */ for (i = 0; i < allocationRequestCount; i++) { if (NULL != allocationRequests[i].address) { - memset((void *) (((UDATA) allocationRequests[i].address) - allocationRequests[i].prefixSize), 0, allocationRequests[i].fragmentSize); + memset((void *) (((UDATA)allocationRequests[i].address) - allocationRequests[i].prefixSize), 0, allocationRequests[i].fragmentSize); } }