Path: blob/master/runtime/gc_base/HotFieldUtil.cpp
5985 views
/*******************************************************************************1* Copyright (c) 2020, 2020 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "j9.h"23#include "j9cfg.h"2425#if defined(J9VM_GC_MODRON_SCAVENGER) || defined(J9VM_GC_VLHGC)2627#include "HotFieldUtil.hpp"28#include "GCExtensions.hpp"2930/* Value used to help with the incrementing of the gc count between hot field sorting for dynamicBreadthFirstScanOrdering */31#define INCREMENT_GC_COUNT_BETWEEN_HOT_FIELD_SORT 1003233/* Minimum hotness value for a third hot field offset if depthCopyThreePaths is enabled for dynamicBreadthFirstScanOrdering */34#define MINIMUM_THIRD_HOT_FIELD_HOTNESS 500003536void37MM_HotFieldUtil::sortAllHotFieldData(J9JavaVM *javaVM, uintptr_t gcCount)38{39MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);4041/* update hottest fields for all elements of the hotFieldClassInfoPool where isClassHotFieldListDirty is true */42if ((NULL != javaVM->hotFieldClassInfoPool) && ((gcCount % extensions->gcCountBetweenHotFieldSort) == 0)) {43omrthread_monitor_enter(javaVM->hotFieldClassInfoPoolMutex);44pool_state hotFieldClassInfoPoolState;45J9ClassHotFieldsInfo *hotFieldClassInfoTemp = (struct J9ClassHotFieldsInfo*)pool_startDo(javaVM->hotFieldClassInfoPool, &hotFieldClassInfoPoolState);4647/* sort hot field list for the class if the hot field list of the class is dirty */48while ((NULL != hotFieldClassInfoTemp) && (U_8_MAX != hotFieldClassInfoTemp->consecutiveHotFieldSelections)) {49if (hotFieldClassInfoTemp->isClassHotFieldListDirty) {50sortClassHotFieldList(javaVM, hotFieldClassInfoTemp);51}52hotFieldClassInfoTemp = (struct J9ClassHotFieldsInfo*)pool_nextDo(&hotFieldClassInfoPoolState);53}54omrthread_monitor_exit(javaVM->hotFieldClassInfoPoolMutex);55}5657/* If adaptiveGcCountBetweenHotFieldSort, update the gc count required between sorting all hot fields as the application runs longer */58if ((extensions->adaptiveGcCountBetweenHotFieldSort) && (extensions->gcCountBetweenHotFieldSort < extensions->gcCountBetweenHotFieldSortMax) && ((gcCount % INCREMENT_GC_COUNT_BETWEEN_HOT_FIELD_SORT) == 0)) {59extensions->gcCountBetweenHotFieldSort++;60}6162/* If hotFieldResettingEnabled, update the gc count required between resetting all hot fields */63if ((extensions->hotFieldResettingEnabled) && ((gcCount % extensions->gcCountBetweenHotFieldReset) == 0)) {64resetAllHotFieldData(javaVM);65}66}6768MMINLINE void69MM_HotFieldUtil::sortClassHotFieldList(J9JavaVM *javaVM, J9ClassHotFieldsInfo* hotFieldClassInfo)70{71MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);7273/* store initial hot field offsets before hotFieldClassInfo hot field offsets are updated */74uint8_t initialHotFieldOffset1 = hotFieldClassInfo->hotFieldOffset1;75uint8_t initialHotFieldOffset2 = hotFieldClassInfo->hotFieldOffset2;76uint8_t initialHotFieldOffset3 = hotFieldClassInfo->hotFieldOffset3;7778/* compute and update the hot fields for each class */79if (1 == hotFieldClassInfo->hotFieldListLength) {80hotFieldClassInfo->hotFieldOffset1 = hotFieldClassInfo->hotFieldListHead->hotFieldOffset;81} else {82J9HotField* currentHotField = hotFieldClassInfo->hotFieldListHead;83uint64_t hottest = 0;84uint64_t secondHottest = 0;85uint64_t thirdHottest = 0;86uint64_t current = 0;87while (NULL != currentHotField) {88if(currentHotField->cpuUtil > extensions->minCpuUtil) {89current = currentHotField->hotness;90/* compute the three hottest fields if depthCopyThreePaths is enabled, or the two hottest fields if only depthCopyTwoPaths is enabled, otherwise, compute just the hottest field if both depthCopyTwoPaths and depthCopyThreePaths are disabled */91if (extensions->depthCopyThreePaths) {92if (current > hottest) {93thirdHottest = secondHottest;94hotFieldClassInfo->hotFieldOffset3 = hotFieldClassInfo->hotFieldOffset2;95secondHottest = hottest;96hotFieldClassInfo->hotFieldOffset2 = hotFieldClassInfo->hotFieldOffset1;97hottest = current;98hotFieldClassInfo->hotFieldOffset1 = currentHotField->hotFieldOffset;99} else if (current > secondHottest) {100thirdHottest = secondHottest;101hotFieldClassInfo->hotFieldOffset3 = hotFieldClassInfo->hotFieldOffset2;102secondHottest = current;103hotFieldClassInfo->hotFieldOffset2 = currentHotField->hotFieldOffset;104} else if (current > thirdHottest) {105thirdHottest = current;106hotFieldClassInfo->hotFieldOffset3 = currentHotField->hotFieldOffset;107}108} else if (extensions->depthCopyTwoPaths) {109if (current > hottest) {110secondHottest = hottest;111hotFieldClassInfo->hotFieldOffset2 = hotFieldClassInfo->hotFieldOffset1;112hottest = current;113hotFieldClassInfo->hotFieldOffset1 = currentHotField->hotFieldOffset;114} else if (current > secondHottest) {115secondHottest = current;116hotFieldClassInfo->hotFieldOffset2 = currentHotField->hotFieldOffset;117}118} else if (current > hottest) {119hottest = current;120hotFieldClassInfo->hotFieldOffset1 = currentHotField->hotFieldOffset;121}122}123currentHotField = currentHotField->next;124}125if (thirdHottest < MINIMUM_THIRD_HOT_FIELD_HOTNESS) {126hotFieldClassInfo->hotFieldOffset3 = U_8_MAX;127}128}129/* if permanantHotFields are allowed, update consecutiveHotFieldSelections counter if hot field offsets are the same as the previous time the class hot field list was sorted */130if (extensions->allowPermanantHotFields) {131if ((initialHotFieldOffset1 == hotFieldClassInfo->hotFieldOffset1) && (initialHotFieldOffset2 == hotFieldClassInfo->hotFieldOffset2) && (initialHotFieldOffset3 == hotFieldClassInfo->hotFieldOffset3)) {132hotFieldClassInfo->consecutiveHotFieldSelections++;133if (hotFieldClassInfo->consecutiveHotFieldSelections == extensions->maxConsecutiveHotFieldSelections) {134hotFieldClassInfo->consecutiveHotFieldSelections = U_8_MAX;135}136} else {137hotFieldClassInfo->consecutiveHotFieldSelections = 0;138}139}140hotFieldClassInfo->isClassHotFieldListDirty = false;141}142143/**144* Reset all hot fields for all classes.145* Used when dynamicBreadthFirstScanOrdering is enabled and hotFieldResettingEnabled is true.146*147* @param javaVM[in] pointer to the J9JavaVM148*/149MMINLINE void150MM_HotFieldUtil::resetAllHotFieldData(J9JavaVM *javaVM)151{152omrthread_monitor_enter(javaVM->hotFieldClassInfoPoolMutex);153pool_state hotFieldClassInfoPoolState;154J9ClassHotFieldsInfo *hotFieldClassInfoTemp = (struct J9ClassHotFieldsInfo *)pool_startDo(javaVM->hotFieldClassInfoPool, &hotFieldClassInfoPoolState);155while (NULL != hotFieldClassInfoTemp) {156J9HotField* currentHotField = hotFieldClassInfoTemp->hotFieldListHead;157while (NULL != currentHotField) {158currentHotField->hotness = 0;159currentHotField->cpuUtil = 0;160currentHotField = currentHotField->next;161}162hotFieldClassInfoTemp = (struct J9ClassHotFieldsInfo*)pool_nextDo(&hotFieldClassInfoPoolState);163}164omrthread_monitor_exit(javaVM->hotFieldClassInfoPoolMutex);165}166167#endif /* J9VM_GC_MODRON_SCAVENGER || J9VM_GC_VLHGC */168169170